Julia epsilon

Julia epsilon,由于位数所限,并不是每个实数都能在计算机中有准确的表达,计算机中的浮点型数值也只是实数集很小的子集之一。所以,计算机中相邻两个浮点型值之间存在着“缝隙”,是其无法表达的实数区域,也影响着科学计算的精度。为了能够评估这种误差,相邻浮点值间这种缝隙的宽度被称为epsilon值

Julia中可通过eps()获得某个浮点值附近的epsilon值,下面以Float64类型的浮点数为例:
Julia epsilon

细心的读者能够发现,浮点值不同时epsilon值也不同

实际上,随着浮点值(绝对值)从大到小,epsilon值会呈指数级骤减,到零值处最小。而且epsilon值的大小关于零点对称,与浮点值的正负无关。换言之,在计算机能够表达的浮点数集合中,越靠近零点,数值的分布越稠密;而远离零点时,则会变得越来越稀疏,精度也会越来越差

也可以直接取得某个浮点类型的epsilon值,代码如下:

julia> eps(Float16)         # 等于eps(one(Float16))
Float16(0.000977)

julia> eps(Float32)         # 等于eps(one(Float32))
1.1920929f-7

julia> eps(Float64)         # 等于eps(one(Float64))
2.220446049250313e-16

julia> eps()                 # 等于eps(one(Float64))
2.220446049250313e-16

不过以类型获得epsilon值时,上报的“缝隙”值实际是浮点值为1.0处的情况。若调用该函数未提供参数,则取默认浮点类型在值为1.0处的epsilon值,例如在64位系统中,esp()相当于eps(one(Float64))

正是由于epsilon值的存在,计算机中的浮点数并不是无限稠密的,而是一系列离散的数值。而且离散的浮点数是有序的,所以可以进行逐一遍历。

内置的nextfloat()prefloat()函数可以分别获得某个浮点值的后继与前继浮点值。例如:

julia> x = 1.25f0
1.25f0

julia> nextfloat(x)
1.2500001f0

julia> prevfloat(x)
1.2499999f0

如果我们查看x及其前继、后继的在二进制表达,便能够发现它们之间的大小只差一个进制位,即:

julia> bitstring(prevfloat(x))
"00111111100111111111111111111111"

julia> bitstring(x)
"00111111101000000000000000000000"

julia> bitstring(nextfloat(x))
"00111111101000000000000000000001"

这实际也是浮点表达中epsilon值存在的重要原因。

当然,也可以通过x+eps(x)x-eps(x)分别获得x的后继与前继值,代码如下:

julia> x + eps(x)                   # 等于nextfloat(x)
1.2500001f0

julia> x - eps(x)                   # 等于nextfloat(x)
1.2499999f0

这样的遍历操作在一些需要高精度数值迭代的场景会比较有用。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!