3 ms·
The number used in that example is called a subnormal or denormalized number [1]. When you get into the really tiny ranges, the fpu can compensate by shifting t
by Sanddancer 11y ago
The number used in that example is called a subnormal or denormalized number [1]. When you get into the really tiny ranges, the fpu can compensate by shifting the number further and further to the right, at the cost of lost accuracy, and a lot of speed. The example given only is only a few binary places from zero [2], so is indeed one of the smallest numbers an fpu can operate on.
One of the things that happens when you enable "unsafe" options is that it sets a flag in the SSE control register to set subnormal numbers to zero. Because subnormal numbers slow things down considerably, making them not happen is one of the unsafe ways to speed up code. Importing that library will run initialization code that sets the control register to get the extra, precision-losing, speed, and as a consequence, set all those tiny numbers to zero, hence the results you see.
[1] https://en.wikipedia.org/wiki/Denormal_number https://en.wikipedia.org/wiki/Denormal_number
[2] http://www.binaryconvert.com/result_double.html?decimal=052046055052051048051048050048048048056101045051050050 http://www.binaryconvert.com/result_double.html?decimal=0520...
- mikeash 11y agoIt makes sense given what's going on, but I think that flags which affect global process behavior when you merely use them in a library ought to be called out much more heavily. The default ought to be to either leave these global flags alone, or save/restore them at the library entry points. If you really want to change the whole global state, it ought to be described as something beyond merely "unsafe" in my opinion.