我在使用浮点变量时听说过"错误".现在我正在尝试解决这个难题,我想我得到了一些舍入/浮点错误.所以我最终要弄清楚浮点错误的基础知识.
什么是浮点/舍入误差的简单示例(最好是在C++中)?
编辑:例如说我有一个成功概率为p的事件.我做了10次此事件(p没有变化,所有试验都是独立的).两次成功试验的概率是多少?我把它编码为:
double p_2x_success = pow(1-p, (double)8) * pow(p, (double)2) * (double)choose(8, 2);
这是浮点错误的机会吗?
图片胜过千言万语 - 尝试绘制方程式f(k)
:
你会得到这样的XY图(X和Y是对数刻度).
如果计算机可以表示没有舍入错误的32位浮点数,那么对于每一个k
我们应该得到零.但是,由于浮点误差累积,误差随着k值的增大而增加.
心连心!
for(double d = 0; d != 0.3; d += 0.1); // never terminates
通常,浮点错误是指无法存储在IEEE浮点表示中的数字.
存储整数,最右边的位为1,左边的每个位是(2,4,8,...)的两倍.很容易看出,它可以存储最多2 ^ n的任何整数,其中n是位数.
浮点数的尾数(小数部分)以类似的方式存储,但是从左向右移动,并且每个连续位是前一个的值的一半.(它实际上比这复杂一点,但它现在会做的).
因此,像0.5(1/2)这样的数字很容易存储,但并不是每个数字<1都可以通过添加固定数量的1/2,1/4,1/8,...的分数来创建.
一个非常简单的例子是0.1或1/10.这可以通过一个无限系列(我真的无法解决这个问题)来完成,但是每当计算机存储0.1时,它就不是存储的数字.
如果您可以访问Unix机器,很容易看到:
Python 2.5.1 (r251:54863, Apr 15 2008, 22:57:26) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 0.1 0.10000000000000001 >>>
无论你使用何种语言,你都要非常小心使用浮点数和双打数进行相等测试.
(至于你的例子,0.2是另一个无法存储在IEEE二进制文件中的讨厌数字,但只要你测试不等式,而不是等式,比如p <= 0.2,那么你就可以了.)
一个简单的C,让我回想起一段时间,
char *c = "90.1000"; double d = 0; sscanf(c,"%f",&d); printf("%0.4f",d); >> 90.0999
这是一个将DMS中的角度转换为弧度的函数,在上述情况下没有.
这是一个吸引我的东西。
round(256.49999) == 256 roundf(256.49999) == 257
加倍和浮动