Julia中的浮点数类型
欢迎关注Julia语言微信公众账号 julia_language
原文链接:http://suo.im/5ehpw8
微信公众号:Julia语言
每周一三五更新,其他时间随机加餐;
问题或建议,请公众号留言;
Julia中的基本数值类型(浮点型)
浮点型.png使用标准方式或科学计数法来表示文本化的浮点数:
julia> 1.0
1.0
julia> 1.
1.0
julia> 0.5
0.5
julia> .5
0.5
julia> -1.23
-1.23
julia> 1e10
1.0e10
julia> 2.5e-4
0.00025
上述结果均为 Float64 值。文本化的 Float32 值也可以直接输入,这时使用 f 来替代 e :
julia> 0.5f0
0.5f0
julia> typeof(ans)
Float32
julia> 2.5f-4
0.00025f0
浮点数也可以很容易地转换为 Float32 :
julia> Float32(-1.5)
-1.5f0
julia> typeof(ans)
Float32
十六进制浮点数的类型,只能为 Float64 :
julia> 0x1p0
1.0
julia> 0x1.8p3
12.0
julia> 0x.4p-1
0.125
julia> typeof(ans)
Float64
Julia 也支持半精度浮点数( Float16 ) ,但只用来存储。计算时,它们被转换为 Float32 :
julia> sizeof(Float16(4.))
2
julia> 2*Float16(4.)
Float16(8.0)
下划线_能被用作数字分隔符
julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010
(10000, 5.0e-9, 0xdeadbeef, 0xb2)
浮点数类型的零
浮点数类型中存在两个零 ,正数的 零和负数的零。它们相等,但有着不同的二进制表示,可以使用 bitstring 函数看出:
julia> 0.0 == -0.0
true
julia> bitstring(0.0)
"0000000000000000000000000000000000000000000000000000000000000000"
julia> bitstring(-0.0)
"1000000000000000000000000000000000000000000000000000000000000000"
特殊的浮点数
有三个特殊的标准浮点数:
三种特殊的标准浮点数.png
按照 IEEE 754 标准 ,这几个值可如下获得:
julia> 1/Inf
0.0
julia> 1/0
Inf
julia> -5/0
-Inf
julia> 0.000001/0
Inf
julia> 0/0
NaN
julia> 500 + Inf
Inf
julia> 500 - Inf
-Inf
julia> Inf + Inf
Inf
julia> Inf - Inf
NaN
julia> Inf * Inf
Inf
julia> Inf / Inf
NaN
julia> 0 * Inf
NaN
typemin 和 typemax 函数也适用于浮点数类型:
julia> (typemin(Float16),typemax(Float16))
(-Inf16, Inf16)
julia> (typemin(Float32),typemax(Float32))
(-Inf32, Inf32)
julia> (typemin(Float64),typemax(Float64))
(-Inf, Inf)
精度
大多数的实数并不能用浮点数精确表示,因此有必要知道两个相邻浮点数间的间距,也即计算机的精度。
Julia 提供了 eps 函数,可以用来检查 1.0 和下一个可表示的浮点数之间的间距:
julia> eps(Float32)
1.1920929f-7
julia> eps(Float64)
2.220446049250313e-16
julia> eps() # same as eps(Float64)
2.220446049250313e-16e
这两个值实际上分别是 2.0^-23(Float32) and 2.0^-52(Float64)。
eps 函数也可以取浮点数作为参数,给出这个值和下一个可表示的浮点数的绝对差,即, eps(x) 的结果与 x
同类型,且满足 x + eps(x) 是下一个比 x 稍大的、可表示的浮点数:
julia> eps(1.0)
2.220446049250313e-16
julia> eps(1000.)
1.1368683772161603e-13
julia> eps(1e-27)
1.793662034335766e-43
julia> eps(0.0)
5.0e-324
函数 nextfloat 和 prevfloat 可以用来获取下一个或上一个浮点数:
julia> x = 1.25f0
1.25f0
julia> nextfloat(x)
1.2500001f0
julia> prevfloat(x)
1.2499999f0
julia> bitstring(prevfloat(x))
"00111111100111111111111111111111"
julia> bitstring(x)
"00111111101000000000000000000000"
julia> bitstring(nextfloat(x))
"00111111101000000000000000000001"
相邻的两个浮点数之间的距离并不是固定的,数值越小,间距越小;数值越大, 间距越大。换句话说,浮点数在0 附近最稠密,随着数值越来越大,数值越来越稀疏,数值间的距离呈指数增长。根据定义, eps(1.0) 与 eps(Float64) 相同,因为 1.0 是 64 位浮点数。
此例显示了邻接的浮点数和它们的二进制整数的表示。
舍入模型
如果一个数没有精确的浮点数表示,那就需要舍入了。可以根据 IEEE 754 标准 来更改舍入的模型。
默认舍入模型为 RoundNearest ,它舍入到最近的可表示的值,这个被舍入的值使用尽量少的有效数字。
背景与参考资料
浮点数的算术运算同人们的预期存在着许多差异,特别是对不了解底层实现的人。许多科学计算的书籍都会详细的解释这些差异。下面是一些参考资料:
- 关于浮点数算数运算最权威的指南是 IEEE 754-2008 标准 ;然而,该指南没有免费的网络版;
- 一个简短但是清晰地解释了浮点数是怎么表示的, 请参考 John D. Cook 的文章 。它还简述了由于浮点数的
表示方法不同于理想的实数会带来怎样的问题; - 推荐 Bruce Dawson 的关于浮点数的博客;
- David Goldberg 的每个计算机科学家都需要了解的浮点数算术计算,是一篇非常精彩的文章,深入讨论了
浮点数和浮点数的精度问题; - 更多资料可以参见“浮点数之父”——William Kahan的文章。