Julia:尝试获取BigFloat

时间:2017-10-07 01:10:15

标签: type-conversion 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

但这非常令人不满意。这是怎么回事?

1 个答案:

答案 0 :(得分:3)

对于BigFloat,问题看起来像trunc中的错误。问题是当前代码(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