Julia:尝试获取BigFloat的整数部分时出现错误
问题描述:
我有兴趣以字节的形式获取BigFloat的数字。我收到一个非常奇怪的错误,我无法调试。我提供了一个出现错误的最小示例。Julia:尝试获取BigFloat的整数部分时出现错误
function floatToBytes(x::BigFloat)
ret = zeros(UInt8, 4)
xs = significand(x)/2
b = UInt8(0)
for i = 1:4
xs *= 256
b = trunc(UInt8, xs)
ret[i] = b
xs -= b
end
return ret
end
println(floatToBytes(BigFloat(0.9921875001164153)))
println(floatToBytes(BigFloat(0.9960937501164153)))
我能得到什么的时候运行,这是
UInt8[0xfe, 0x00, 0x00, 0x00]
ERROR: LoadError: InexactError()
Stacktrace:
[1] trunc(::Type{UInt8}, ::BigFloat) at ./mpfr.jl:201
等
看来,它不希望把255变成UInt8
。我可以通过将功能定义为
function floatToBytes(x::BigFloat)
ret = zeros(UInt8, 4)
xs = significand(x)/2
b = UInt8(0)
for i = 1:4
xs *= 256
try
b = trunc(UInt8, xs)
catch
b = trunc(UInt8, xs-1)+UInt8(1)
end
ret[i] = b
xs -= b
end
return ret
end
但是这是非常不令人满意的。这里发生了什么?
答
这个问题看起来像是BigFloat的trunc
中的一个bug。问题是当前代码(typemin(T) <= x <= typemax(T)) || throw(InexactError(:trunc, T, x))
会引发错误,因为x
大于255,这是typemax。
它实际上需要在BigFloat域中执行trunc
,然后将其转换为T(并且对typemax进行转换检查)。
我已经打开,在这方面的问题:https://github.com/JuliaLang/julia/issues/24041
在此期间,一个解决办法是要做到:
UInt8(trunc(xs))
即trunc
第一,后来投。例如:
julia> UInt8(trunc(BigFloat(0.9960937501164153)*256))
0xff
它看起来像是BigFloat的'trunc'中的一个bug。它做'(typemin(T)
啊,你能做到吗? – tst
当然,你可以在函数中使用'UInt8(trunc(BigFloat(0.9960937501164153)* 256))'或'UInt8(trunc(xs))'。我也可以写这个答案。 –