World: r3wp
[!REBOL3-OLD1]
older newer | first last |
Ladislav 2-Jul-2009 [15896x2] | but, anyway, I am still pretty sure, that such a difference actually is undetectable |
yes, you would have to run the test "almost forever" to see anything | |
Geomol 2-Jul-2009 [15898] | A test could be to run random 1.0 many many times and save the results coming close to zero. Like my other test, checking if the result is within the first 1024 number close to zero. After running the test many times, a picture can be seen. |
Ladislav 2-Jul-2009 [15899x2] | for random 1.0 you cannot find any irregularities, there aren't any |
(the random numbers you may obtain are regularly spaced in that case) | |
Geomol 2-Jul-2009 [15901] | ah yes. :) You need larger numbers. Up to what number is the distance between numbers the same? 2.0? |
Ladislav 2-Jul-2009 [15902x3] | for sure, if the difference should be detectable, then you should try random 2 ** 1023 |
- in that case the chances are much higher, that you could detect any irregularities | |
do I understand correctly, that you prefer the variant including both endpoints? | |
Geomol 2-Jul-2009 [15905] | yes |
Ladislav 2-Jul-2009 [15906] | ...and your main reason is, that you know the endpoints exactly? |
Geomol 2-Jul-2009 [15907] | I'm in doubt about the distribution of numbers. Is this R2 function calculating ulps between two number ok? ulps: func [ value1 value2 /local d1 d2 ][ d: make struct! [v [decimal!]] none d1: make struct! [hi [integer!] lo [integer!]] none d2: make struct! [hi [integer!] lo [integer!]] none d/v: value1 change third d1 third d d/v: value2 change third d2 third d print [d1/hi d1/lo d2/hi d2/lo] print [d1/hi - d2/hi * (2 ** 32) + d1/lo - d2/lo] ] |
Ladislav 2-Jul-2009 [15908] | suggestion: R3 |
Geomol 2-Jul-2009 [15909] | The reason, I prefer your first version is: - I always know the endpoints exactly. - The mean is well defined. - The function is simpler and faster. |
Ladislav 2-Jul-2009 [15910x2] | REBOL [ Author: "Ladislav Mecir" Purpose: {Converts decimal to ordinal and back} ] make object! [ int-min: to integer! #{8000000000000000} set 'dec-as-int func [x [decimal!]] [ x: to integer! to binary! x either x < 0 [int-min - x] [x] ] set 'int-as-dec func [x [integer!]] [ if x < 0 [x: int-min - x] to decimal! to binary! x ] ] |
your "difference in ulps" is just the difference between the ordinal numbers | |
Geomol 2-Jul-2009 [15912x2] | So an R3 ulps could be: ulps: func [ lo [decimal!] hi [decimal!] ][ (to-integer to-binary hi) - to-integer to-binary lo ] |
>> ulps 0.0 0.1 == 4591870180066957722 >> ulps 0.1 0.2 == 4503599627370496 | |
Ladislav 2-Jul-2009 [15914] | (as-int hi) - (as-int lo) |
Geomol 2-Jul-2009 [15915] | It seems, numbers lie much closer around zero than around 0.1. |
Ladislav 2-Jul-2009 [15916] | sorry, (dec-as-int hi) - (dec-as-int lo) |
Geomol 2-Jul-2009 [15917x2] | >> (dec-as-int 0.1) - (dec-as-int 0.0) == 4591870180066957722 >> (dec-as-int 0.2) - (dec-as-int 0.1) == 4503599627370496 Same result. Now I'm confused! :-) |
If this is correct, then my suggestion to do random 1.0 many times will actually show the problem. | |
Ladislav 2-Jul-2009 [15919x2] | yes, you get different result only when trying (dec-as-int 0.0) - (dec-as-int -0.0) |
etc. | |
Geomol 2-Jul-2009 [15921x5] | The highest decimal is >> to-decimal #{7fef ffff ffff ffff} == 1.79769313486232e+308 There is the same number of ulps between 0.0 and 2.0 as between 1.0 and the highest decimal: >> ulps 0.0 2.0 == 4611686018427387904 >> ulps 1.0 to-decimal #{7fef ffff ffff ffff} == 4611686018427387903 I think, the space between number are different all the way from zero to the highest decimal, but I'm not sure. |
space between *numbers* are ... | |
Funnily enough, 1.5 is the middle value when talking ulps: >> ulps 0.0 1.5 == 4609434218613702656 >> ulps 1.5 hi == 4609434218613702655 | |
where hi is: hi: to-decimal #{7fef ffff ffff ffff} | |
This mean, there is as many different possible decimals between 0.0 and 1.5 as between 1.5 and the highest possible 64-bit decimal, when talking floating points in a computer using the 64-bit IEEE 754 standard. | |
Ladislav 2-Jul-2009 [15926x2] | how about this, do you think, that there is a problem with it too? two**62: to integer! 2 ** 62 two**9: to integer! 2 ** 9 two**53: to integer! 2 ** 53 r-uni: func [x [decimal!] /local d] [ d: random two**62 ; transform to 0..2**53-1 d: d // two**53 ; transform to 0.0 .. x (0.0 inclusive, x exclusive) d / two**53 * x ] |
a modification: two**62: to integer! 2 ** 62 two**53: to integer! 2 ** 53 two**53+1: two**53 + 1 r-uni: func [x [decimal!] /local d] [ d: random two**62 ; transform to 0..2**53 d: d // two**53+1 ; transform to 0.0 .. x (0.0 inclusive, x inclusive) d / two**53 * x ] | |
BrianH 2-Jul-2009 [15928] | When you two are done, could you look at CureCode ticket #1027 and R3's alpha 66 behavior and see if it is correct? I can't judge. |
Ladislav 2-Jul-2009 [15929x2] | LOL, that is what we are just discussing |
anyway, this is always a problem, when we try to generate numbers in an "exotic" interval, not in the usual [0.0 .. 1.0] | |
Geomol 2-Jul-2009 [15931] | I'll just grab some food, then I look at your r-uni. |
Ladislav 2-Jul-2009 [15932] | hmm, seems, that the former may still produce X when rounding? |
Gregg 2-Jul-2009 [15933] | In any case, this chat should be the basis for the docs that go with it. People aren't aware of how much thought goes into these things. |
Geomol 2-Jul-2009 [15934x2] | >> two**62 / two**53+1 == 512.0 So two**53+1 * 512 should equal two**62, but it doesn't: >> two**62 == 4611686018427387904 >> two**53+1 * 512 == 4611686018427388416 Why is that? |
(I wanted to check , if d // two**53+1 gave an even distribution, but there seem to be something wrong with calculations of large numbers.) | |
Ladislav 2-Jul-2009 [15936] | Why is that? - rounding |
Geomol 2-Jul-2009 [15937] | This should give an math overflow, I think: >> to integer! 2 ** 62 == 4611686018427387904 Like this does in R2: >> to integer! 2 ** 31 ** Math Error: Math or number overflow |
Ladislav 2-Jul-2009 [15938] | no, R3 uses 64-bit integers |
Geomol 2-Jul-2009 [15939x3] | no wait, it's 2 ** 63, that should give overflow. |
yeah | |
But!? :-) >> to integer! 2 ** 62 - 1 == 4611686018427387904 >> to integer! 2 ** 62 == 4611686018427387904 Isn't that a bug? | |
Ladislav 2-Jul-2009 [15942] | no, it is the precision limit of IEEE754 |
Geomol 2-Jul-2009 [15943] | I see. |
Ladislav 2-Jul-2009 [15944] | (I mean, it exceeds the precision limit) |
Geomol 2-Jul-2009 [15945] | Yes, I understand. |
older newer | first last |