双精度浮点数和单精度浮点数,双精度浮点数表示
1.希望找到问题,得到一个长度为57的数组,从0开始,间隔为0.01。当然,我想用下面的方式编码,但结果却出乎意料:
Importnumpyasnpt1=NP。Arange (0,0.01 * 0.01) T1.shape) 58L)然而,如果可以通过相同的方法获得长度为58且从0开始间隔为0.01的正确数组,则结果是
T2=NP。Arange (0,0.01 * 0.01) T2.shape) 58L,)什么问题?
2.浮点数的精度。我找到了一些资料,但是很混乱。为了理解为什么会出现上述问题,通过总结和整理列出了几个重要内容。
)python的浮点,在计算机中用二进制表示小数,和C语言的double类型很像。其实应该是一样的,但毕竟标准python是用c写的)是双精度浮点类型,可以按原样用十进制数或科学记数法表示。每个双精度浮点数占用8个字节(64位),完全符合IEEE754标准(52M/11E/1S)。也就是说,52位表示基数,11位表示指数,剩下的1位表示符号。虽然它看起来非常完美,但实际的准确性取决于机器架构和创建python解释器的编译器。
尝试用二进制形式表示0.1。通过下面的计算可以看出,0.1在十进制中是一个有限小数,在二进制中是一个无限循环。(实际上,在0.0~0.9的十位小数中,二进制中只有0.0和0.5是有限的。) :
根据IEEE754标准,有效数字只能代表52位数字。在python中,0.1实际上是这样表示的。(python不提供。bin函数,只是。十六进制函数)。
(0.1),十六进制),)0x1.9999999999AP-4 )0x是十六进制数,P-4表示小数点左移4位。IEEE754标准的52位在这里小数点前不含1,所以展开0x 1.9999999999 AP-4 时,会显示:
原表达式:0.00011001100110011001 1001 1001 1001 1001 1001 1001 1001 # ie 0011001101
大蟒
print“% . 20f“%(0.1)0.1000000000000000000555 print“% . 20f“%”0 . 1 . 1)0.200000000000110 print“% . 20f”int“% . 20f“%(0 . 10 . 2)0.30000000000000441 print“% . 20f“%(0.1 * 3)0.30000000000000000004441
d : (developvitest。CPP # include iostream # includeiomanipusingnamespacestd;int main () { double a=0.1,b=0.2,c=0.3int d=3;cout 0.1= set precision(20)aendl;cout 0 . 10 . 1= set precision(20)a aendl;cout 0.2= set precision(20)bendl;cout 0 . 10 . 2= set precision(20)a bendl;cout 0.1 * 3= set precision(20)a* dendl;cout 0.3= set precision(20)cendl;} : wqd :developgt est。test.exe 0.1=0.1000000000550.1=0.200
000000000000001110.2=0.2000000000000000000000110.1 0.2=0.300000000000000044410.1 * 3=0.30000000000000000000044410.3=0.3.
编程语言中的0.3其实比数学中的0.3小一点;但是当0.1 0.2或者0.1*3运算时,编程语言中的误差会随之而来,运算的结果会累积误差,导致它在数学上比0.3大一点。
numpy.arange中使用浮点数的问题分析
根据以上分析,我们可以解释使用numpy.arange的现象我们可以验证一下:
导入numpy为np np.arange(0,0.1*3,0.1)数组([ 0。0.1,0.2,0.3]) np.arange(0,0.3,0.1)数组([ 0 .0.1,0.2])print“% . 20f”%(0.57)0.56999999995115 print“% . 20f”%(0.01 * 57)0.5700000006217 print“% . 20f”%(0.01如果表示最终值的第二个参数使用了0.1*3,但实际使用了一个略大于0.3的数,那么根据numpy.arange的使用规则(生成的数组确实而直接用0.3作为最终值,因为实际上比0.3小一点,所以得到的数组不会包含0.3。同样,0.01*57是比0.57略大的数,所以生成的数组自然包含0.57(但实际上是比0.57略小的数),你得不到预期的数组。然而,这是合理的。后来我发现,大家写numpy.arange的时候就已经说了,如果用非整数作为步长,最好用numpy.linspace(不过好像我遇到了stop的问题。
帮助.阿兰格(.)arange([start,] stop[,step,],dtype=None).当使用非整数步长(如0.1)时,结果通常会不一致。对于这种情况,最好使用“linspace”。3.解决方案(numpy.arange问题的解决方案要尽量避免使用arange!您可以使用xrange:
将numpy作为NP t1=NP . array([x * 0.01 for x in xrange(57)])t1 . shape(57L,)T2=NP . array([x * 0.01 for x in xrange(58)])T2 . shape(58L,)(2)求解小数
from Decimal import Decimal D1=Decimal(. 1)D2=Decimal( 1.0 )D3=Decimal( 1.0 )D1 Decimal( 0.10000000000005551151231257827021181583404541015625 )D2 Decimal( 0.1 )D3 Decimal( 1.0 )D1 1.0 trace back(最近一次调用最后一次):File stdin ,第1行,在House中