Floating point Julia中的精确十进制算法

Floating point Julia中的精确十进制算法,floating-point,julia,multiplication,Floating Point,Julia,Multiplication,由于Julia中的,.4*.4=0.1600000000000003。我想以CPU效率高的方式得到数学上正确的答案0.16。我知道round()可以工作,但这需要事先知道答案所占的小数位数,因此它不是一个通用的解决方案。一些选项: 使用内置的Rational类型。最准确、最快的方法是 16//100*16//100 如果您使用的是非常大的数字,这些数字可能会溢出,在这种情况下,您可以使用BigInts big(16)//big(100) * big(16)//big(100) (实际上,您不需

由于Julia中的,
.4*.4
=
0.1600000000000003
。我想以CPU效率高的方式得到数学上正确的答案
0.16
。我知道round()可以工作,但这需要事先知道答案所占的小数位数,因此它不是一个通用的解决方案。

一些选项:

  • 使用内置的
    Rational
    类型。最准确、最快的方法是

    16//100*16//100

  • 如果您使用的是非常大的数字,这些数字可能会溢出,在这种情况下,您可以使用
    BigInt
    s

    big(16)//big(100) * big(16)//big(100)
    
    (实际上,您不需要将它们全部包装在
    big
    s中,因为配给将自动升级)

    您也可以使用
    rationalize(0.16)
    ,但这可能不太准确或有效,因为Julia看到
    0.16
    文本时,它已经被转换为
    Float64
    ,因此您将转换为二进制浮点,然后再转换为
    Rational

  • 包装十进制浮点的英特尔实现。这应该是相当快的(虽然没有二进制那么有效),但有固定的精度,所以您必须在某个点进行取整

  • 是一个“大十进制”浮点库:由于它使用任意精度的算术运算,它将比DecFP慢


  • 要说哪个是最好的,需要更多关于您的预期用途的信息。

    您可以将Python的
    decimal.decimal
    PyCall
    结合使用,但效率将受到Python的限制

    导入包:

    julia> using PyCall
    
    julia> @pyimport decimal
    
    julia> const Dec = decimal.Decimal
    PyObject <class 'decimal.Decimal'>
    
    用它们做一些数学运算:

    julia> x = Dec("0.4")
    PyObject Decimal('0.4')
    
    julia> x * x
    PyObject Decimal('0.16')
    
    julia> x + x
    PyObject Decimal('0.8')
    
    julia> x - x
    PyObject Decimal('0.0')
    
    julia> x / x
    PyObject Decimal('1')
    
    julia> y = x + x * x / x - x
    PyObject Decimal('0.4')
    
    获取结果:

    julia> y[:to_eng_string]() |> float
    0.4
    

    浮点数学已经得到解决。事实上,这个具体的案例是由这些问题引起的,这可能是OP正在寻找的答案。第二部分(如何在Julia中得到正确答案)似乎是合理的。。。毕竟,他并不热衷于使用浮点运算。“什么是cpu占用最少的方式”-当你甚至还没有正确性时,为什么还要关心性能呢?Julia中的一个合理选择是有理算术:
    4//10*4//10
    ->
    4//25
    ,以及
    float(4//25)的结果
    确实是最接近于0.16的浮点数。请尝试@BarryGackle,我同意,我已编辑以解决这个问题。考虑下一次编辑你自己。抱歉,但是我不会带所有的Python来解决这个问题,当Steven Johnson的DEFFP.JL包工作得很好时,不会给朱丽亚增加很多开销,甚至比使用BigFalk更快。请注意,DecFP.jl也比使用内置的BigFloat类型快(因为使用了不可变)
    julia> y[:to_eng_string]() |> float
    0.4