Closed
Description
Hi,
I found some strange behavior hat might be a missing edge case when converting typemax(UInt64)
from-and-to Float64
.
In the following code, the neighbouring numbers of Float64(typemax(UInt64))
are converted to UInt64
again. The bigger such neighbours throw an InexactError, where the smaller ones perform the conversion.
But UInt64(Float64(typemax(UInt64)))
(case b2
below) does something strange
a2 = typemax(UInt64) # 0xffffffffffffffff
f1 = nextfloat(Float64(a2)) # 1.8446744073709556e19
f2 = Float64(a2) # 1.8446744073709552e19
f3 = prevfloat(Float64(a2)) # 1.8446744073709550e19
f4 = prevfloat(prevfloat(Float64(a2))) # 1.8446744073709548e19
f5 = prevfloat(prevfloat(prevfloat(Float64(a2)))) # 1.8446744073709545e19
# ...
b1 = UInt64(f1) # InexactError ✓
b2 = UInt64(f2) # 0x8000000000000000 ↯↯↯
b3 = UInt64(f3) # 0xfffffffffffff800 ✓
b4 = UInt64(f4) # 0xfffffffffffff000 ✓
b5 = UInt64(f5) # 0xffffffffffffe800 ✓
# ...
there is a similar issue with Float32
a2 = typemax(UInt32) # 0xffffffff
f1 = nextfloat(Float32(a2)) # 4.2949680f9
f2 = Float32(a2) # 4.2949673f9
f3 = prevfloat(Float32(a2)) # 4.2949670f9
f4 = prevfloat(prevfloat(Float32(a2))) # 4.2949668f9
f5 = prevfloat(prevfloat(prevfloat(Float32(a2)))) # 4.2949665f9
# ...
b1 = UInt32(f1) # InexactError ✓
b2 = UInt32(f2) # 0x00000000 ↯↯↯
b3 = UInt32(f3) # 0xffffff00 ✓
b4 = UInt32(f4) # 0xfffffe00 ✓
b5 = UInt32(f5) # 0xfffffd00 ✓
# ...
and a bit worse situation with Float16
a2 = typemax(UInt16) # 0xffff
f1 = nextfloat(Float16(a2)) # Inf16 ☝️🧐
f2 = Float16(a2) # Inf16 ☝️🧐
f3 = prevfloat(Float16(a2)) # Float16(6.550e4)
f4 = prevfloat(prevfloat(Float16(a2))) # Float16(6.547e4)
f5 = prevfloat(prevfloat(prevfloat(Float16(a2)))) # Float16(6.544e4)
# ...
b1 = UInt16(f1) # 0x0000 ↯↯↯
b2 = UInt16(f2) # 0x0000 ↯↯↯
b3 = UInt16(f3) # 0xffe0 ✓
b4 = UInt16(f4) # 0xffc0 ✓
b5 = UInt16(f5) # 0xffa0 ✓
# ...
Is this intended, or just on my system? I would expect the ↯↯↯-cases to throw an inexact error.
Julia Version 1.7.1
Commit ac5cc99908* (2021-12-22 19:35 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-13.0.0 (ORCJIT, skylake)
Environment:
JULIA_LOAD_PATH = /usr/share/gmsh/api/julia/:
JULIA_EDITOR = code
JULIA_NUM_THREADS = 4