Closed vassvik closed 5 years ago
Just checking in to confirm that both the rounding bug and the fmt
bug are still happening.
Sorry 😛
This appears to be an LLVM issue with regards to encoding 32 bit floating point numbers: https://github.com/odin-lang/Odin/blob/master/src/ir_print.cpp#L621
u64 u = bit_cast<u64>(value.value_float);
switch (type->Basic.kind) {
case Basic_f32:
// IMPORTANT NOTE(bill): LLVM requires all floating point constants to be
// a 64 bit number if bits_of(float type) <= 64.
// https://groups.google.com/forum/#!topic/llvm-dev/IlqV3TbSk6M
// 64 bit mantissa: 52 bits
// 32 bit mantissa: 23 bits
// 16 bit mantissa: 10 bits
// 29 == 52-23
u >>= 29;
u <<= 29;
break;
// case Basic_f16:
// u >>= 42;
// u <<= 42;
// break;
}
Confirmed to still be broken:
$ odin run main.odin
true
false
294967296.000 4294967040.000
This is a difficult one as I am not sure how to fix it without loads of hacks. This is a design fault of LLVM.
Just re-ran the example code and this appears to be working when using version 8.0.1 of LLVM binaries.
@thebirk I fixed the problem by doing an explicit bit cast from an integer to a float instead of trying to represent the float correctly. LLVM is stupid.
The following snippet:
will output
It does not seem to be only large values, as you can find in-between values where it works as expected.
It seems to be related to floating point rounding:
which will output:
which seems to indicate that the former rounds up, while the latter rounds down.