Taking a GCC 12.2.0 compilation on a Pi 4B Bookworm 32-bit as the reference I see what I would expect on the Pi 4B, but when the same code is run on an RP2040 or RP235X I see different results to what are expected.
The first question would be; is my IEEE 754 interpretation correct and the native Pi reference correct, as should be expected ?
If so; does that mean the Pico SDK is buggy, both for the RP2040 and RP235X ?
Pi 4BRP2040
The issues here are different for 32-bit float and 64-bit double, and no NaN for 64-bit double is notableRP2350 ARM and/or RISC-V
The issues here appear to be the same for both 32-bit float and 64-bit double
The first question would be; is my IEEE 754 interpretation correct and the native Pi reference correct, as should be expected ?
If so; does that mean the Pico SDK is buggy, both for the RP2040 and RP235X ?
Code:
#include <stdio.h>union ieee_754_single_32bit { float f; unsigned int u;} s;union ieee_754_double_64bit { double f; unsigned long long u;} d;int main(void) { // .------------------------------------------------. // | Single floating point IEEE 754 32-bit integers | // `------------------------------------------------' // // seee eeee emmm mmmm mmmm mmmm mmmm mmmm // // s--- ---- ---- ---- ---- ---- ---- ---- // -eee eeee e--- ---- ---- ---- ---- ---- // ---- ---- -mmm mmmm mmmm mmmm mmmm mmmm // // 0000 0000 0000 0000 0000 0000 0000 0000 0.0 // 0000 0000 0mmm mmmm mmmm mmmm mmmm mmmm 0.0 // 1000 0000 0000 0000 0000 0000 0000 0000 -0.0 // 1000 0000 0mmm mmmm mmmm mmmm mmmm mmmm -0.0 // s.u = 0x00000000; printf("%08X is %f\n", s.u, s.f); // 0.0 s.u = 0x0000FFFF; printf("%08X is %f\n", s.u, s.f); // 0.0 s.u = 0x80000000; printf("%08X is %f\n", s.u, s.f); // -0.0 s.u = 0x8000FFFF; printf("%08X is %f\n", s.u, s.f); // -0.0 // // 0111 1111 1000 0000 0000 0000 0000 0000 inf // 0111 1111 1mmm mmmm mmmm mmmm mmmm mmmm nan // 1111 1111 1000 0000 0000 0000 0000 0000 -inf // 1111 1111 1mmm mmmm mmmm mmmm mmmm mmmm -nan // s.u = 0x7F800000; printf("%08X is %f\n", s.u, s.f); // inf s.u = 0x7F80FFFF; printf("%08X is %f\n", s.u, s.f); // nan s.u = 0xFF800000; printf("%08X is %f\n", s.u, s.f); // -inf s.u = 0xFF80FFFF; printf("%08X is %f\n", s.u, s.f); // -nan // .------------------------------------------------. // | Double floating point IEEE 754 64-bit integers | // `------------------------------------------------' // // seee eeee eeee mmmm .... mmmm mmmm mmmm // // s--- ---- ---- ---- .... ---- ---- ---- // -eee eeee eeee ---- .... ---- ---- ---- // ---- ---- ---- mmmm .... mmmm mmmm mmmm // // 0000 0000 0000 0000 .... 0000 0000 0000 0.0 // 0000 0000 0000 mmmm .... mmmm mmmm mmmm 0.0 // 1000 0000 0000 0000 .... 0000 0000 0000 -0.0 // 1000 0000 0000 mmmm .... mmmm mmmm mmmm -0.0 // d.u = 0x0000000000000000; printf("%016llX is %f\n", d.u, d.f); // 0.0 d.u = 0x000000000000FFFF; printf("%016llX is %f\n", d.u, d.f); // 0.0 d.u = 0x8000000000000000; printf("%016llX is %f\n", d.u, d.f); // -0.0 d.u = 0x800000000000FFFF; printf("%016llX is %f\n", d.u, d.f); // -0.0 // // 0111 1111 1111 0000 .... 0000 0000 0000 inf // 0111 1111 1111 mmmm .... mmmm mmmm mmmm nan // 1111 1111 1111 0000 .... 0000 0000 0000 -inf // 1111 1111 1111 mmmm .... mmmm mmmm mmmm -nan // d.u = 0x7FF0000000000000; printf("%016llX is %f\n", d.u, d.f); // inf d.u = 0x7FF000000000FFFF; printf("%016llX is %f\n", d.u, d.f); // nan d.u = 0xFFF0000000000000; printf("%016llX is %f\n", d.u, d.f); // -inf d.u = 0xFFF000000000FFFF; printf("%016llX is %f\n", d.u, d.f); // -nan}Code:
00000000 is 0.0000000000FFFF is 0.00000080000000 is -0.0000008000FFFF is -0.0000007F800000 is inf7F80FFFF is nanFF800000 is -infFF80FFFF is -nanCode:
0000000000000000 is 0.000000000000000000FFFF is 0.0000008000000000000000 is -0.000000800000000000FFFF is -0.0000007FF0000000000000 is inf7FF000000000FFFF is nanFFF0000000000000 is -infFFF000000000FFFF is -nanThe issues here are different for 32-bit float and 64-bit double, and no NaN for 64-bit double is notable
Code:
00000000 is 0.0000000000FFFF is 0.00000080000000 is 0.000000<--- Should be -0.0000008000FFFF is -0.0000007F800000 is inf7F80FFFF is nanFF800000 is -infFF80FFFF is nan<--- Should be -nanCode:
0000000000000000 is 0.000000000000000000FFFF is 0.0000008000000000000000 is 0.000000<--- Should be -0.000000800000000000FFFF is 0.000000<--- Should be -0.0000007FF0000000000000 is inf7FF000000000FFFF is inf<--- Should be nanFFF0000000000000 is -infFFF000000000FFFF is -inf<--- Should be -nanThe issues here appear to be the same for both 32-bit float and 64-bit double
Code:
00000000 is 0.0000000000FFFF is 0.00000080000000 is 0.000000<--- Should be -0.0000008000FFFF is -0.0000007F800000 is inf7F80FFFF is nanFF800000 is -infFF80FFFF is nan<--- Should be -nanCode:
0000000000000000 is 0.000000000000000000FFFF is 0.0000008000000000000000 is 0.000000<--- Should be -0.000000800000000000FFFF is -0.0000007FF0000000000000 is inf7FF000000000FFFF is nanFFF0000000000000 is -infFFF000000000FFFF is nan<--- Should be -nanStatistics: Posted by hippy — Tue Jul 29, 2025 1:45 pm