4 ms·
I remember being told a long time ago by our graphics programmer that the result of a floating point operation might be different depending on the state of the
by MikeDucker 14y ago
I remember being told a long time ago by our graphics programmer that the result of a floating point operation might be different depending on the state of the FPU. A quick internet search brings up things like this: http://www.codercorner.com/FPUFun.htm http://www.codercorner.com/FPUFun.htm which talks about setting the default rounding mode of the FPU. Not sure if that's what he was talking about, but it certainly bears no reference to my issue as I'm certainly not explicitly setting anything like that.
That being that case can you give a reasonable explanation why carrying out ( x * y ) then later that function / y gave a value for x that casting would keep as x, when leaving the y division until sometime much later during the run resulted in a value of x - 1? There must have been something different between the two runs apart from literal time, but if nothing is hidden, then what is the difference that made the difference?
- acqq 14y agoAs far as I understand, you are not sure what your code does when. If you'd follow the steps of the code you wrote, you'd see that when the same values travel the same code paths they end up being always exactly the same. In programming the different results can come only from the different steps, unless you change the environment (which would be your intentional rounding mode change or if you read some uninitialized memory).
- MikeDucker 14y agoI would follow the steps again (I am genuinely interested in learning why it does what it does), but I ripped out the scaling factor a few days ago and reintroducing it in the hope that the same thing happens would be a lot of work, hence asking if there was some obvious reason that might be causing what I'm seeing. There must be some step I'm not appreciating or some state that's different. If something like this happens again I'll take a closer look into it.
- acqq 14y agoWhen you cross the line from the integers to the ten times smaller values (step 1) you move from the finite universe to the "approximate" one, unless the staring number ended with 0 or 5 and you divided with the exact constant 10 (even multiplying with .1 is not for all inputs the same as dividing with 10 because "exactly .1" doesn't exist in base 2 FP -- as another commenter said it's not the math you know from the school -- look at the bits). Once you are in the approximate world (it's in fact exact for itself but from your starting position not what you had or you think you have) you can exactly follow when you get the expected result and when you get what you haven't expected, but the real cause is always that in the step 1 you've lost an infinite(!) number of bits. If you don't want to worry, just don't do divisions with 10. Divide with 8 or 16 or 32...
- MikeDucker 14y agoI think that's excellent advice, which I'll take if I end up using box2D in the end :)
- scott_s 14y agoIf you'd follow the steps of the code you wrote, you'd see that when the same values travel the same code paths they end up being always exactly the same. Unless, of course, the "code paths" you're talking about are at the C level. In that case, it is possible for optimizations (or lack of it) to end up with slightly different values for the same C code. How often things are moved in and out of the FPU registers can impact things (as I point out elsewhere), as well as if the C compiler orders operations differently.
- acqq 14y agoOnce one code path is optimized it is what it is, there can be nothing "slightly different" as long as your code is the same, if you get different results for the same inputs you don't follow the same path. When you change the code, you have the brand new landscape -- it's you who changed it. Moving out of the FPU registers will happen in always the same points before you change the code, and even where moving out occurs you won't observe 80 bits partial results unless you intentionally turn that feature on. If you have any specific counterexample I happily welcome it.
- scott_s 14y agoOnce one code path is optimized it is what it is, there can be nothing "slightly different" as long as your code is the same You have missed my point. For the author, he thinks of "the code" as the C code that he can see. The fact that passing different compiler flags may result in "the code" ending up in different machine code is not something he's used to thinking about. So you have to be careful when explaining such concepts to beginners.
- acqq 14y agoI disagree. Changing FP optimizations is not something that can surprise anybody in producing different results. If the results were exactly the same we wouldn't need different options in the compiler as there wouldn't be a trade off to decide about. It's the "religious" claims (presenting very well thought-through engineering as if some god, magic or a random number generator is inside, it's not) that motivate some people to say things like "we'll never know." You won't if you approach it dogmatically or fatalisticaly.