Mail Archives: djgpp-workers/2000/05/19/09:18:09
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
- Raw text -