float32的准确性

时间:2016-08-25 00:31:55

标签: python numpy floating-point floating-accuracy

为了减少文件大小,我正在尝试将float64数据保存到float32中的文件中。数据值通常介于1e-12到10.我在将float64转换为float32时测试了准确度损失。

print np.finfo('float32')

显示

Machine parameters for float32
---------------------------------------------------------------
precision=  6   resolution= 1.0000000e-06
machep=   -23   eps=        1.1920929e-07
negep =   -24   epsneg=     5.9604645e-08
minexp=  -126   tiny=       1.1754944e-38
maxexp=   128   max=        3.4028235e+38
nexp  =     8   min=        -max
---------------------------------------------------------------

结果float32的分辨率为1e-6,而abs值的有效范围仅为1.2e-38

import numpy as np

x = 2.0*np.random.rand(100) - 1.0 # make random numbers in [-1, 1]

print('x.dtype: %s'%(x.dtype)) # outputs float64

print('number :  max_error  max_relative_error')
for i in xrange(-40, 1):
    y = x * 10**i
    print('1e%-4d:  %s'%(i, np.max(np.abs(y - y.astype('f4').astype('f8')))))

结果

number:    max_error       max_relative_error
1e-40 :    6.915620e-46    6.915620e-06
1e-39 :    6.910361e-46    6.910361e-07
1e-38 :    6.949349e-46    6.949349e-08
1e-37 :    4.816590e-45    4.816590e-08
1e-36 :    4.303771e-44    4.303771e-08
1e-35 :    3.518621e-43    3.518621e-08
1e-34 :    5.165854e-42    5.165854e-08
1e-33 :    3.660088e-41    3.660088e-08
1e-32 :    3.660088e-40    3.660088e-08
1e-31 :    4.097193e-39    4.097193e-08
1e-30 :    4.615068e-38    4.615068e-08
1e-29 :    3.696983e-37    3.696983e-08
1e-28 :    2.999860e-36    2.999860e-08
1e-27 :    4.723454e-35    4.723454e-08
1e-26 :    3.801082e-34    3.801082e-08
1e-25 :    3.062408e-33    3.062408e-08
1e-24 :    4.876378e-32    4.876378e-08
1e-23 :    3.779378e-31    3.779378e-08
1e-22 :    3.144592e-30    3.144592e-08
1e-21 :    4.991049e-29    4.991049e-08
1e-20 :    3.949261e-28    3.949261e-08
1e-19 :    3.002761e-27    3.002761e-08
1e-18 :    5.162480e-26    5.162480e-08
1e-17 :    4.135703e-25    4.135703e-08
1e-16 :    3.282146e-24    3.282146e-08
1e-15 :    4.722129e-23    4.722129e-08
1e-14 :    3.863295e-22    3.863295e-08
1e-13 :    3.375549e-21    3.375549e-08
1e-12 :    4.011790e-20    4.011790e-08
1e-11 :    4.011790e-19    4.011790e-08
1e-10 :    3.392060e-18    3.392060e-08
1e-9  :    5.471206e-17    5.471206e-08
1e-8  :    4.072652e-16    4.072652e-08
1e-7  :    3.496987e-15    3.496987e-08
1e-6  :    5.662626e-14    5.662626e-08
1e-5  :    4.412957e-13    4.412957e-08
1e-4  :    3.482083e-12    3.482083e-08
1e-3  :    5.597344e-11    5.597344e-08
1e-2  :    4.620014e-10    4.620014e-08
1e-1  :    3.540690e-09    3.540690e-08
1e0   :    2.817751e-08    2.817751e-08

对于高于1e-38的值,1e-8的相对误差大约为1e-6,低于np.finfo提出的tiny,即使值低于{1},误差仍然可以接受np.finfo的{​​{1}}值。

float32中保存我的数据看起来是安全的,但我很好奇测试看起来与np.finfo的结果不一致?

2 个答案:

答案 0 :(得分:4)

低于正常范围的数字。基本上,指数没有足够的范围来获得足够低的值,因此随着值的降低,你逐渐失去重要的位。这被称为“逐渐下溢”。

https://en.wikipedia.org/wiki/Denormal_number

答案 1 :(得分:1)

由于机器浮点epsilon是1.1920929e-07,因此舍入将使相对误差在正常浮点数的一半之内:5.9604645e-8。但是,当你小于1.1754944e-38时,你有非规范化数字,而绝对误差为1.4012985e-45。