realmax function and maximum float64 number

582 views
Skip to first unread message

Beata Szostakowska

unread,
Oct 26, 2014, 4:38:07 PM10/26/14
to julia...@googlegroups.com
I was trying to experimentally find the maximum number for type float64. The number I got is 8.98846567431158e 307. However built-in function realmax(Float64) returns 1.7976931348623157e308.  What is the reason of this difference?
This is my code to find maximum number:

temp = 1.
max = 1.

    while !isinf(max)
           temp = max
           max *= 2.
    end

max = temp


Stefan Karpinski

unread,
Oct 27, 2014, 6:45:59 PM10/27/14
to Julia Users
You're skipping a lot of floating-point numbers every time you double your max value. Your code computes the largest representable power of two, not the largest representable Float64. The general representation of a Float64 is:

1 bit sign
11 bits of exponent
52 bits of digits after the leading 1 (which is implied)

Your code starts with 1.0 which has these bits:

0
01111111111
0000000000000000000000000000000000000000000000000000

This decodes as 1.0*2^(1023-1023) – i.e. one. When you double it, you get 2.0, which is

0
10000000000
0000000000000000000000000000000000000000000000000000

As you can see, the data part is still all zeros and the only thing that happened is that the exponent 1024 instead of 1023. This keeps happening each time you double. Soon you get to 8.98846567431158e307, which has these bits:

0
11111111110
0000000000000000000000000000000000000000000000000000

The next exponent value is 0b11111111111 == 2047, which is only used to represent infinities and NaNs so the next time you double, the correct value would be larger that is possible to represent, so you get Inf. This is where your code stops. However, there are lots more values bigger that this that don't have all zero data – you can get almost twice as big. In particular, we would expect that this representation to be the largest finite value:

0
11111111110
1111111111111111111111111111111111111111111111111111

Indeed, that is exactly the bits of 1.7976931348623157e308:

julia> bits(realmax())
"0111111111101111111111111111111111111111111111111111111111111111"

As expected, this is almost – but not quite – twice as big as 8.98846567431158e307:

julia> 1.7976931348623157e308/8.98846567431158e307
1.9999999999999998

I can think of a few ways to experimentally find the maximum Float64, but it's hard to reconcile mentally because I can just write the bits of the number down :-). It's exactly this:

julia> reinterpret(Float64, 0b0111111111101111111111111111111111111111111111111111111111111111)
1.7976931348623157e308

Also, you can just use integer arithmetic to find the float right before Inf:

julia> reinterpret(Float64, reinterpret(Uint64, Inf) - 1)
1.7976931348623157e308

Anyway, that's probably more explanation than anyone needed but I couldn't resist.

Jiahao Chen

unread,
Oct 27, 2014, 10:57:53 PM10/27/14
to julia...@googlegroups.com
There is also

julia> prevfloat(Inf)
1.7976931348623157e308

Simon Byrne

unread,
Oct 28, 2014, 8:09:09 AM10/28/14
to julia...@googlegroups.com
When playing around with floating point numbers, I find a function like the following helps a lot to see what they look like underneath:

decode(x::Float32) = (b=bits(x); (b[1], b[2:9], b[10:32]))
decode(x::Float64) = (b=bits(x); (b[1], b[2:12], b[13:64]))

or, very soon, you will be able to use @printf "%a" x to get a hexadecimal representation.

s

Reply all
Reply to author
Forward
0 new messages