关于c ++:浮点/舍入错误的简单示例是什么?

What is a simple example of floating point/rounding error?

使用浮点变量时,我听说过"错误"。 现在,我正在尝试解决这个难题,并且我想遇到一些舍入/浮点错误。 因此,我最终将弄清浮点错误的基础。

浮点/舍入误差的一个简单示例是什么(最好在C ++中)?

编辑:例如,说我有一个事件,其成功概率为p。 我进行了10次此活动(p不变,所有试验都是独立的)。 两次成功试验的概率是多少? 我将此编码为:

1
double p_2x_success = pow(1-p, (double)8) * pow(p, (double)2) * (double)choose(8, 2);

这是浮点错误的机会吗?


图片值一千个字-尝试画出等式f(k)enter image  description here,您会得到这样的XY图(X和Y以对数标度表示)。
enter image description here
如果计算机可以表示32位浮点数而没有舍入错误,则对于每个k,我们应该得到零。但是相反,由于浮点误差累积,误差随着k的值增大而增加。

心连心!


1
 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计算机,则很容易看到以下内容:

1
2
3
4
5
6
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语言让我回想起

1
2
3
4
5
6
char *c ="90.1000";
double d = 0;
sscanf(c,"%f",&d);
printf("%0.4f",d);

>> 90.0999

这是将DMS中的角度转换为弧度的功能,而在上述情况下则没有。


这是一个吸引我的东西。

1
2
 round(256.49999) == 256
roundf(256.49999) == 257

加倍和浮动


我喜欢Python解释器中的这个:

1
2
3
4
5
6
Python 2.7.10 (default, Oct  6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type"help","copyright","credits" or"license" for more information.
>>> 0.1+0.2
0.30000000000000004
>>>


超级简单:

1
2
3
4
5
a = 10000000.1
b = 1/10
print(a - b == 10000000)
print ('a:{0:.20f}
b:{1:.20f}'
.format(a, b))

打印(取决于平台)类似以下内容:

1
2
3
False                                                                                                                                
a:10000000.09999999962747097015                                                                                                      
b:0.10000000000000000555