今天,我在看一些c++代码(别人写的),发现了这一部分:
double someValue = ...
if (someValue < std::numeric_limits<double>::epsilon() &&
someValue > -std::numeric_limits<double>::epsilon()) {
someValue = 0.0;
}
我在想这到底说得通不合理。
epsilon()的文档说:
该函数返回1与可[用双精度符号]表示的大于1的最小值之间的差值。
这是否也适用于0,即()的最小值大于0?或者有没有0到0 +之间的数可以用双精度数表示?
如果不是,那么比较是不是等同于someValue == 0.0?
假设我们正在使用适合16位寄存器的玩具浮点数。有一个符号位,一个5位指数和一个10位尾数。
这个浮点数的值是尾数,解释为二进制十进制值,乘以2的指数次方。
在1附近,指数等于0。尾数中最小的数字是1024的1分之一。
接近1/2的指数是- 1,所以尾数最小的部分是一半大。如果是5位指数,它可以达到负16,此时尾数最小的部分值为3200万分之一。在- 16指数处,这个值大约是32k的1分之1,比我们上面计算的1附近更接近于0 !
这是一个玩具式的浮点模型,它不能反映真正的浮点系统的所有怪癖,但是它反映小于的值的能力与真正的浮点值相当相似。
假设我们正在使用适合16位寄存器的玩具浮点数。有一个符号位,一个5位指数和一个10位尾数。
这个浮点数的值是尾数,解释为二进制十进制值,乘以2的指数次方。
在1附近,指数等于0。尾数中最小的数字是1024的1分之一。
接近1/2的指数是- 1,所以尾数最小的部分是一半大。如果是5位指数,它可以达到负16,此时尾数最小的部分值为3200万分之一。在- 16指数处,这个值大约是32k的1分之1,比我们上面计算的1附近更接近于0 !
这是一个玩具式的浮点模型,它不能反映真正的浮点系统的所有怪癖,但是它反映小于的值的能力与真正的浮点值相当相似。
Also, a good reason for having such a function is to remove "denormals" (those very small numbers that can no longer use the implied leading "1" and have a special FP representation). Why would you want to do this? Because some machines (in particular, some older Pentium 4s) get really, really slow when processing denormals. Others just get somewhat slower. If your application doesn't really need these very small numbers, flushing them to zero is a good solution. Good places to consider this are the last steps of any IIR filters or decay functions.
请参见:为什么将0.1f更改为0会使性能降低10倍?
和http://en.wikipedia.org/wiki/Denormal_number