Message-Id: <200005191256.IAA07803@delorie.com> From: "Dieter Buerssner" To: djgpp-workers AT delorie DOT com Date: Fri, 19 May 2000 15:02:56 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: rand() in libc In-reply-to: <200005191159.NAA08580@lws256.lu.erisoft.se> References: <200004271315 DOT JAA03708 AT delorie DOT com> from "Dieter Buerssner" at Apr 27, 2000 04:20:23 PM X-mailer: Pegasus Mail for Win32 (v3.12b) Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On 19 May 00, at 13:59, Martin Stromberg wrote: > Dieter said: > > A more natural approach seems to me to just do > > > > s2*2^-16 + s1*2^-32 + s0*2^-48; > > Ok, how doI easily say 2^-16, 2^-32 and 2^-48 to the compiler? Is it > ok to use pow(2, -16) etc. (efficiency)? You certainly don't want to use pow(). How about 1.52587890625E-5 * s2 + 2.3283064365386962890625E-10 * s1 + 3.552713678800500929355621337890625E-15 * s0; In my experience, the decimal to binary conversion of gcc is very reliable. You can check this, by looking at the assembler output. All three constants must have zero mantissa digits only. If you don't want to rely on the correct dec->bin conversion of gcc, I can give you the constants as an array of two unsigned longs, that can be casted to type double. You can optimize the three multiplications to one multiplication, by first shifting s2,s1 and s0 into an signed long long, and then multiply by 2^-48. /* Untested */ signed long long ll; unsigned short s2, s1, s0; /* In the actual code your state array */ ll = (signed long long)(s0 | ((unsigned long)s1 << 16) |((unsigned long long)s2 << 32)); return ll * 3.552713678800500929355621337890625E-15; or even return ll * (1.0/(1LL << 48)); Signed long long is used, because the FPU has no upcode for loading unsigned long long integers. Regards, Dieter