RE: 53-bit double

2022-07-04 Thread Dr Greg Low
Hi Greg,

All good. I think you described it fine. The question I had was more on what 
the big picture was. Why do it at all?

And yes, there’d be a way to manipulate the bits to manually construct it, but 
in most languages, that’d be pretty ugly anyway.

Regards,

Greg

Dr Greg Low

1300SQLSQL (1300 775 775) office | +61 419201410 mobile
SQL Down Under | Web: https://sqldownunder.com<https://sqldownunder.com/> | 
About Greg:  https://about.me/greg.low

From: Greg Keogh 
Sent: Tuesday, 5 July 2022 8:58 AM
To: Dr Greg Low 
Cc: ozDotNet 
Subject: Re: 53-bit double

I might have missed it earlier Greg but was the actual problem that this helps 
with? I was intrigued by the underlying problem.

I didn't express myself clearly originally. I was trying to convert a 64-bit 
random integer into a double and guarantee that all possible 2^53 floating 
values in the range 0 to 1 could result. Someone suggested that weird bit of 
earlier incomprehensible code, but it turns out a simple shift-and-multiply 
does that trick.

There are lots of modern PRNGs that generate 64-bits, like the xoroshift** that 
is being used in the latest Random class. But how do you convert 64-bits 
"perfectly" into doubles? I finally confirmed a correct way.

I'm still wondering if there is a way of manually constructing an IEEE 754 
number from the raw bits, but it makes my head hurt.

Cheers, GK


Re: 53-bit double

2022-07-04 Thread Greg Keogh
>
> I might have missed it earlier Greg but was the actual problem that this
> helps with? I was intrigued by the underlying problem.
>

I didn't express myself clearly originally. I was trying to convert a
64-bit random integer into a double and guarantee that all possible 2^53
floating values in the range 0 to 1 could result. Someone suggested that
weird bit of earlier incomprehensible code, but it turns out a simple
shift-and-multiply does that trick.

There are lots of modern PRNGs that generate 64-bits, like the xoroshift**
that is being used in the latest Random class. But how do you convert
64-bits "perfectly" into doubles? I finally confirmed a correct way.

I'm still wondering if there is a way of manually constructing an IEEE 754
number from the raw bits, but it makes my head hurt.

Cheers, *GK*


RE: 53-bit double

2022-07-04 Thread Dr Greg Low
I might have missed it earlier Greg but was the actual problem that this helps 
with? I was intrigued by the underlying problem.

Regards,

Greg

Dr Greg Low

1300SQLSQL (1300 775 775) office | +61 419201410 mobile
SQL Down Under | Web: https://sqldownunder.com<https://sqldownunder.com/> | 
About Greg:  https://about.me/greg.low

From: Greg Keogh via ozdotnet 
Sent: Tuesday, 5 July 2022 8:37 AM
To: ozDotNet 
Cc: Greg Keogh 
Subject: Re: 53-bit double

uint u1 = [32 random bits];
uint u2 = [32 random bits];
uint a = u1 >> 5, b = u2 >> 6;
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);

Can anyone explain this magic? Is this correct?

This bit trick is no longer important to decode. I was trying to figure out how 
to convert a UInt64 of random bits into a normalised double in the range [0,1) 
in such a way that all 2^53 possible floating values could be produced. Some 
web sites suggested simply doing this:

uint u = [64 random bits]
double d = (u >> 11) * 1.11022302462515654e-16   // * 2-53

I was suspicious that subtle rounding problems might produce a defective output 
range, but a quick experiment in LINQPad that fed limit values into the 
calculation demonstrated that a complete set of significand bit patterns was 
generated at the limits. This supplies good evidence that the above 
shift-and-multiply converts 53 of the 64 random bits into a complete possible 
double range.

Greg K


Re: 53-bit double

2022-07-04 Thread Greg Keogh
>
> uint u1 = *[32 random bits]*;
> uint u2 = *[32 random bits]*;
> uint a = u1 >> 5, b = u2 >> 6;
> return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
>
> Can anyone explain this magic? Is this correct?
>

This bit trick is no longer important to decode. I was trying to figure out
how to convert a UInt64 of random bits into a normalised double in the
range [0,1) in such a way that all 2^53 possible floating values could be
produced. Some web sites suggested simply doing this:

uint u = *[64 random bits]*
double d = (u >> 11) * 1.11022302462515654e-16   // * 2-53

I was suspicious that subtle rounding problems might produce a defective
output range, but a quick experiment in LINQPad that fed limit values into
the calculation demonstrated that a complete set of significand bit
patterns was generated at the limits. This supplies good evidence that the
above shift-and-multiply converts 53 of the 64 random bits into a complete
possible double range.

*Greg K*