sollten Sie verwenden:
(24//10 - 12im//10)/(7//10 - 6im//10)
statt.
Warum passiert das? Die Zahlen, die Sie schreiben, sind Fließkommazahlen - sie sind nicht 0,7 oder 2,4, sondern eher Näherungswerte dieser Zahlen. Sie können diesen Effekt sehen, indem auf eine Rational Umwandlung:
julia> Rational{Int64}(0.7)
3152519739159347//4503599627370496
Der //
Operator in Ihrer Frage verwendet haben eine implizite Konvertierung in rationals, so dass die Ergebnisse wie diese eingehalten werden.
Warum ist ein OverflowError
aufgetreten? Weil der Typ Rational{Int64}
ist, was bedeutet, dass sowohl Zähler als auch Nenner nur Zahlen innerhalb des Bereichs Int64
speichern können. Beachten Sie, was passiert, wenn wir versuchen, diese Zahl zu quadrieren, zum Beispiel:
julia> Rational{Int64}(0.7) * Rational{Int64}(0.7)
ERROR: OverflowError()
in *(::Rational{Int64}, ::Rational{Int64}) at ./rational.jl:196
in eval(::Module, ::Any) at ./boot.jl:234
in macro expansion at ./REPL.jl:92 [inlined]
in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46
Die OverflowError
sagen uns, dass die resultierenden rational nicht mehr exakt darstellbare in dieser Art, die eine gute Sache-schließlich ist der ganze Punkt von Rational
ist genau zu sein! Dies könnte mit Rational{BigInt}
behoben werden, aber natürlich kommt das mit einer erheblichen Leistungseinbuße.
So ist die Wurzel des Problems, dass 0.7
und dergleichen Gleitkommaliterale sind, und sind daher nicht genau 0.7
. In der Tat ausgedrückt ist 0.7
0.6999999999999999555910790149937383830547332763671875
. Stattdessen vermeidet die Verwendung von 7//10
das Problem.
Vielen Dank für die Erklärung! Jetzt weiß ich, dass Sie Floats nicht in Rationals verwenden können (weil Floats nicht genau sind). – Kevin
Ich habe dies vor einiger Zeit als Julia-Bug gemeldet und Simon Byrne hat einen Fix, der darin besteht, diese Verwendung von // zu verbieten. Auf einem Telefon können die Referenzen hier also nicht gleich gestellt werden. –