diff options
| author | drochner <drochner@NetBSD.org> | 2006-03-22 21:06:03 +0000 |
|---|---|---|
| committer | drochner <drochner@NetBSD.org> | 2006-03-22 21:06:03 +0000 |
| commit | 7a2af2aba0675e60300e041f8514eb775a203229 (patch) | |
| tree | f50f6fbde7e7e191372c66d1f95fb3b7043329f9 /lib/libc/stdlib | |
| parent | e89a43e9fd4f84bfb3004474083438814d0f8674 (diff) | |
Rewrite erand48() to put the random bits into the mantissa by simple
bitshifts instead of calling ldexp() three times.
(for ieee doubles only -- vax can't use it, so the old version
needs to stay around)
This removes the dependency on ldexp() which also didn't participate in
the usual __RENAME game, thus lead to confusion.
In addition, this version is almost 3 times as fast for me.
Diffstat (limited to 'lib/libc/stdlib')
| -rw-r--r-- | lib/libc/stdlib/erand48_ieee754.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/libc/stdlib/erand48_ieee754.c b/lib/libc/stdlib/erand48_ieee754.c new file mode 100644 index 00000000000..f3874502875 --- /dev/null +++ b/lib/libc/stdlib/erand48_ieee754.c @@ -0,0 +1,47 @@ +/* $NetBSD: erand48_ieee754.c,v 1.1 2006/03/22 21:06:03 drochner Exp $ */ + +/* + * Copyright (c) 1993 Martin Birgmeier + * All rights reserved. + * + * You may redistribute unmodified or modified versions of this source + * code provided that the above copyright notice and this and the + * following conditions are retained. + * + * This software is provided ``as is'', and comes with no warranties + * of any kind. I shall in no event be liable for anything that happens + * to anyone/anything when using this software. + */ + +#include <sys/cdefs.h> +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: erand48_ieee754.c,v 1.1 2006/03/22 21:06:03 drochner Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include <assert.h> +#include <machine/ieee.h> + +#include "rand48.h" + +#ifdef __weak_alias +__weak_alias(erand48,_erand48) +#endif + +double +erand48(unsigned short xseed[3]) +{ + union ieee_double_u u; + + _DIAGASSERT(xseed != NULL); + + __dorand48(xseed); + u.dblu_dbl.dbl_sign = 0; + u.dblu_dbl.dbl_exp = DBL_EXP_BIAS; /* so we get [1,2) */ + u.dblu_dbl.dbl_frach = ((unsigned int)xseed[0] << 4) + | ((unsigned int)xseed[1] >> 12); + u.dblu_dbl.dbl_fracl = (((unsigned int)xseed[1] & 0x0fff) << 20) + | ((unsigned int)xseed[2] << 4); + return (u.dblu_d - 1); +} |
