How do I convert a Float64 number to Int64?

Hello,
Is it possible to convert a Float64 number directly to Int64?

julia> number=6.5
6.5

julia> typeof(num)
Float64

julia> Int(number)
ERROR: InexactError: Int64(6.5)
Stacktrace:
 [1] Int64(x::Float64)
   @ Base ./float.jl:912
 [2] top-level scope
   @ REPL[22]:1

Thank you.

If the number doesn’t have an integer value (like 6.0), you must round. Then you must decide what sort of rounding you want:

round(Int, x)  # closest int
floor(Int, x)  # downwards 
ceil(Int, x) # upwards

There are some more variations, like trunc.

5 Likes

A mostly useless but reversible alternative to semantic conversion: reinterpret(Int64, x::Float64)

Hi,
Thank you so much.

Some Float64 numbers have Integer values (e.g. -4.0, 0.0, 1.0, 64.0). They convert to Int64 directly.

julia> Int64(-4.0), Int64(0.0), Int64(64.0)
(-4, 0, 64)

Some Float64 values are too large (positive or negative) to fit in an Int64. Many Float64 values exceed the magnitude of largest Int64 (typemax(Int64)).


julia> Int64(Float64(typemax(Int64)/2))
4611686018427387904

julia> Int64(3*Float64(typemax(Int64)/2))
ERROR: InexactError: Int64(1.3835058055282164e19)
Stacktrace:
 [1] Int64(x::Float64)
   @ Base .\float.jl:994
 [2] top-level scope
   @ REPL[26]:1

To convert Float64 values that are small enough for Int64s, you must set the fractional part of the Float64 to 0
(e.g. 3.14 → 3.0 or 4.0, 5.5 → 5.0 or 6.0). There are different rounding modes you may choose to use for this purpose.

pos =  2.5
neg = -2.5
round(pos, RoundUp), round(neg, RoundUp)
# (3.0, -2.0)
round(pos, RoundDown), round(neg, RoundDown)
# (2.0, -3.0)
round(pos, RoundToZero), round(neg, RoundToZero)
# (2.0, -2.0)
round(pos, RoundFromZero), round(neg, RoundFromZero)
# (3.0, -3.0)

# RoundNearest resolves values halfway between (x.5)
# by choosing the nearest even
round(pos, RoundNearest), round(neg, RoundNearest)
# (2.0, -2.0)
# RoundNearestTiesAway and RoundNearestTiesUp also work round(pos, RoundNearestTiesAway), round(neg, RoundNearestTiesAway)
# (3.0, -3.0)
round(3.5, RoundNearestTiesAway), round(-3.5 RoundNearestTiesAway)
# (4.0, -4.0)



round(pos, RoundNearestTiesUp), round(neg, RoundNearestTiesUp)
# (3.0, -2.0)

Whichever rounding mode you use, once the fractional part is rounded away, it will convert to an Int64 as long as it fits.

Int64(round(pi, RoundUp)), Int64(round(-pi, RoundNearest))
(4, -3)

Julia lets you combine the two steps.

round(Int64, pi, RoundUp), round(Int64, -pi, RoundNearest)
(4, -3)

fyi trunc(Int64, x) works like Int64(round(x, RoundToZero)).

4 Likes

Hi,
Thank you so much for these great examples.

Not so useless :slight_smile: We use it in Roots,jl to make a more robust Bisection method (Roots.jl/src/Bracketing/bisection.jl at master · JuliaMath/Roots.jl · GitHub).

2 Likes

I question that you need to convert to integers ever.

You can’t do it in general, e.g.

julia> typemax(Int64)  # this 19-digit number is the max.
922337203685477580

julia> Int64(999_999_999_999_999.0)  # Float64 has 15 significant digits, and number up to this size should be safe:
999999999999999

julia> Int64(9_999_999_999_999_9999.0)  # This is seemingly the first number that fails:
10000000000000000

julia> Int64(round(999_999_999_999_9993.4))  # Fail
9999999999999994

Float64, and even Float32 (but not Float16) allow way larger integers than can fit into Int64:

julia> Int64(round(floatmax(Float32)))
ERROR: InexactError: Int64(3.4028235e38)

julia> BigInt(round(floatmax(Float32)))
340282346638528859811704183484516925440
1 Like