the nature of floating-point math, .4 * .4
= 0.16000000000000003
Julia'da. 0.16
'un matematiksel olarak doğru cevabını CPU-verimli bir şekilde elde etmek istiyorum. Round() çalışmalarını biliyorum, ancak bu sorunun cevabının ondalık basamak sayısı hakkında önceden bilgisi olmasını gerektirir, bu yüzden genel bir çözüm değildir.Julia'da tam onlu aritmetik
cevap
bazı seçenekler:
dahili
Rational
türünü kullanın. En doğru ve en hızlı şekilde,16 // 100 * 16 // 100
bunun yerine BigInt
kullanabilirsiniz s bu durumda bu taşabilir çok büyük sayılar kullanıyorsanız,
big(16)//big(100) * big(16)//big(100)
(rationals otomatik teşvik edecektir olarak aslında, big
s hepsini sarmak için gerekmez).
Ayrıca rationalize(0.16)
kullanabilirsiniz, ancak bu edebi 0.16
zaten Julia gördüğü zaman bir Float64
dönüştürüldükten gibi bir ikili kayan nokta dönüştürme ediyoruz, böylece, oldukça olduğunca doğru veya verimli olmayabilir ve daha sonra Rational
'a.
IEEE-754 ondalık kayan nokta Intel uygulanmasını sarar . Bu, mantıklı bir şekilde hızlı olmalı (ikili kadar verimli olmasa da), ancak sabit bir hassasiyete sahip olmalıdır, bu yüzden bir noktada yuvarlanmanız gerekecektir.
Decimals.jl bir "büyük ondalık" kayan nokta kitaplığıdır: isteğe bağlı kesinlik aritmetiğini kullandığından, DecFP'den daha yavaş olacaktır.
Hangisi en iyisi, kullanım amacınız hakkında daha fazla bilgi gerektirdiğini söylemek.
Not: DecFP.jl ayrıca yerleşik BigFloat türünü kullanmadan * daha hızlı * olduğunu unutmayın (immutables kullanarak) –
Sen Python en decimal.Decimal
PyCall
ile ancak verimlilik Python
julia> using PyCall
julia> @pyimport decimal
julia> const Dec = decimal.Decimal
PyObject <class 'decimal.Decimal'>
Ben tanımların bu tür tüm olması gerektiğini düşünüyorum (operasyonlarını Meta tanımlamak PyCall
parçası):!
julia> py_methods = Dict(
:+ => :__add__,
:* => :__mul__,
:- => :__sub__,
(:/) => :__truediv__
)
Dict{Symbol,Symbol} with 4 entries:
:/ => :__truediv__
:+ => :__add__
:* => :__mul__
:- => :__sub__
julia> for (op, meth) in py_methods
op = Expr(:quote, op)
meth = Expr(:quote, meth)
@eval Base.($op){T<:PyObject}(x::T, y::T) = x[$meth](y)
end
onlarla bazı matematik yapın:
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')
al sonucu:
julia> y[:to_eng_string]() |> float
0.4
Üzgünüz, ama Steven Johnson DecFP.jl paketi, bunu çözmek için tüm Python'u getirmezdim. Çok iyi çalışıyor, Julia'ya fazla yük getirmiyor ve BigFloat'ı kullanmaktan daha hızlı! –
Kayan nokta matematik ele alınmıştır. Bu özel durumun bu sorunlardan kaynaklanmış olması, OP'nin aradığı cevap olabilir. İkincisi (Julia'da doğru cevabı nasıl alacağınız) kısmı meşru görünüyor ... Kayan nokta kullanmak için her şeyden sonra değil. –
"En düşük cpu yoğun yolu nedir" - niçin daha doğrusu olmadığın zaman, performansa neden önem veriyorsun? –
Julia'da makul bir seçenek rasyonel aritmetik: '4 // 10 * 4 // 10' ->' 4 // 25', ve 'float (4 // 25)' sonucu gerçekten en yakın kayan nokta sayısıdır 0.16'ya. –