2016-07-17 18 views
4

Als ich Julia (0.4.3) wollen (2.4 - 1.2im) // (0.7 - 0.6im) zu berechnen, gibt es einen Überlauffehler:Warum gibt dieser komplexe Rational einen Überlauffehler in Julia?

ERROR: OverflowError() 
in * at rational.jl:188 
in // at rational.jl:45 
in // at rational.jl:42 

jedoch (24 - 12 im) // (0.7 - 0.6im), mathmatically essentialy gleich, funktioniert. Auch funktioniert (2.4 - 1.2im)/(0.7 - 0.6im) auch, aber das gibt natürlich kein vernünftiges.

Ist das ein Fehler, oder mache ich etwas falsch? Gibt es Rationale, mit denen Julia nicht arbeiten kann?

Antwort

5

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.70.6999999999999999555910790149937383830547332763671875. Stattdessen vermeidet die Verwendung von 7//10 das Problem.

+0

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

+1

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. –