Reputation: 745
When I want Julia (0.4.3) to compute (2.4 - 1.2im) // (0.7 - 0.6im)
, it gives an overflow error:
ERROR: OverflowError()
in * at rational.jl:188
in // at rational.jl:45
in // at rational.jl:42
However (24 - 12 im) // (0.7 - 0.6im)
, mathmatically essentialy the same, does work. Also, (2.4 - 1.2im) / (0.7 - 0.6im)
works too but this doesn't give a rational of course.
Is this a bug, or am I doing something wrong? Are there rationals that Julia can't work with?
Upvotes: 3
Views: 276
Reputation: 12051
You should use:
(24//10 - 12im//10) / (7//10 - 6im//10)
instead.
Why does this happen? The numbers you write are floating point numbers—they are not 0.7 or 2.4, but rather approximations of those numbers. You can see this effect by converting to a Rational:
julia> Rational{Int64}(0.7)
3152519739159347//4503599627370496
The //
operator used in your question did an implicit conversion to rationals, so results like these are observed.
Now why did an OverflowError
occur? Because the type is Rational{Int64}
, which means both numerator and denominator can only store numbers within the range of an Int64
. Note what happens when we try to square this number, for instance:
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
The OverflowError
tells us that the resulting rational is no longer exactly representable in this type, which is a good thing—after all, the whole point of Rational
is to be exact! This could be fixed with Rational{BigInt}
, but of course that comes with a substantial performance penalty.
So the root of the issue is that 0.7
and the like are floating point literals, and are therefore not exactly 0.7
. Indeed, expressed exactly, 0.7
is 0.6999999999999999555910790149937383830547332763671875
. Instead, using 7//10
avoids the issue.
Upvotes: 4