diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-11 11:34:47 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-11 11:34:47 -0200 |
commit | 51316f9df7aacb54633a3e9b910a070590ac6259 (patch) | |
tree | 954c50a7b11ace095e8a2ca70e31832230e902cb /testes/math.lua | |
parent | 46beca5bed8a7700b18100fe48a78373be5055f9 (diff) | |
download | lua-51316f9df7aacb54633a3e9b910a070590ac6259.tar.gz lua-51316f9df7aacb54633a3e9b910a070590ac6259.tar.bz2 lua-51316f9df7aacb54633a3e9b910a070590ac6259.zip |
'math.rand()' uses higher bits to produce float value
The call 'math.rand()' converts the higher bits of the internal unsigned
integer random to a float, instead of its lower bits. That ensures that
Lua compiled with different float precisions always generates equal (up
to the available precision) random numbers when given the same seed.
Diffstat (limited to 'testes/math.lua')
-rw-r--r-- | testes/math.lua | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/testes/math.lua b/testes/math.lua index 7c780e59..dc5b84f6 100644 --- a/testes/math.lua +++ b/testes/math.lua | |||
@@ -823,17 +823,19 @@ do | |||
823 | assert(random(0) == res) | 823 | assert(random(0) == res) |
824 | 824 | ||
825 | math.randomseed(1007, 0) | 825 | math.randomseed(1007, 0) |
826 | -- using lower bits to generate random floats; (the '% 2^32' converts | 826 | -- using higher bits to generate random floats; (the '% 2^32' converts |
827 | -- 32-bit integers to floats as unsigned) | 827 | -- 32-bit integers to floats as unsigned) |
828 | local res | 828 | local res |
829 | if floatbits <= 32 then | 829 | if floatbits <= 32 then |
830 | -- get all bits from the lower half | 830 | -- get all bits from the higher half |
831 | res = (l & ~(~0 << floatbits)) % 2^32 | 831 | res = (h >> (32 - floatbits)) % 2^32 |
832 | else | 832 | else |
833 | -- get 32 bits from the lower half and the rest from the higher half | 833 | -- get 32 bits from the higher half and the rest from the lower half |
834 | res = ((h & ~(~0 << (floatbits - 32))) % 2^32) * 2^32 + (l % 2^32) | 834 | res = (h % 2^32) * 2^(floatbits - 32) + ((l >> (64 - floatbits)) % 2^32) |
835 | end | 835 | end |
836 | assert(random() * 2^floatbits == res) | 836 | local rand = random() |
837 | assert(eq(rand, 0x0.7a7040a5a323c9d6, 2^-floatbits)) | ||
838 | assert(rand * 2^floatbits == res) | ||
837 | end | 839 | end |
838 | 840 | ||
839 | math.randomseed(0, os.time()) | 841 | math.randomseed(0, os.time()) |