Floating point subnormals are not handled correctly #1582

Open
opened 2023-12-17 17:44:55 -06:00 by dpgeorge · 3 comments
dpgeorge commented 2023-12-17 17:44:55 -06:00 (Migrated from github.com)

It seems that subnormal floats are not handled by the ROM float routines, and the pico-sdk wrappers don't account for this.

Code to reproduce on pico-sdk 1.5.1 (EDIT: fixed typo where it used to say one = 0):

#include <math.h>

static void pr(float f_in) {
    volatile float f = f_in;
    const uint8_t *b = (void *)&f;
    printf("%02x:%02x:%02x:%02x\n", b[0], b[1], b[2], b[3]);
}

int main(int argc, char **argv) {
    stdio_init_all();

    union {
        volatile float f;
        volatile uint32_t i;
    } x;
    volatile float zero = 0;
    volatile float one = 1;

    x.i = 29972;
    pr(x.f);
    pr(x.f + zero);
    pr(x.f * one);

    x.i = 2997220;
    pr(x.f);
    pr(x.f + zero);
    pr(x.f * one);

    return 0;
}

Output is:

14:75:00:00
00:00:00:00
00:00:00:00
e4:bb:2d:00
00:00:00:00
00:00:00:00

It should be:

14:75:00:00
14:75:00:00
14:75:00:00
e4:bb:2d:00
e4:bb:2d:00
e4:bb:2d:00

Above are just some simple examples, but most other operations on subnormals also return incorrect results (according to IEEE).

It seems that subnormal floats are not handled by the ROM float routines, and the pico-sdk wrappers don't account for this. Code to reproduce on pico-sdk 1.5.1 (EDIT: fixed typo where it used to say `one = 0`): ```c #include <math.h> static void pr(float f_in) { volatile float f = f_in; const uint8_t *b = (void *)&f; printf("%02x:%02x:%02x:%02x\n", b[0], b[1], b[2], b[3]); } int main(int argc, char **argv) { stdio_init_all(); union { volatile float f; volatile uint32_t i; } x; volatile float zero = 0; volatile float one = 1; x.i = 29972; pr(x.f); pr(x.f + zero); pr(x.f * one); x.i = 2997220; pr(x.f); pr(x.f + zero); pr(x.f * one); return 0; } ``` Output is: ``` 14:75:00:00 00:00:00:00 00:00:00:00 e4:bb:2d:00 00:00:00:00 00:00:00:00 ``` It should be: ``` 14:75:00:00 14:75:00:00 14:75:00:00 e4:bb:2d:00 e4:bb:2d:00 e4:bb:2d:00 ``` Above are just some simple examples, but most other operations on subnormals also return incorrect results (according to IEEE).
lurch commented 2023-12-17 17:58:30 -06:00 (Migrated from github.com)

volatile float one = 0;
Is that a bug, or just a typo? 😉

`volatile float one = 0;` Is that a bug, or just a typo? :wink:
dpgeorge commented 2023-12-17 18:02:05 -06:00 (Migrated from github.com)

Is that a bug, or just a typo?

Ooops! That's a typo. I just tested it again with the fixed typo and the output is as in the original post (ie the subnormal bug is there).

> Is that a bug, or just a typo? Ooops! That's a typo. I just tested it again with the fixed typo and the output is as in the original post (ie the subnormal bug is there).
dpgeorge commented 2023-12-17 18:04:49 -06:00 (Migrated from github.com)

Note that the volatile's are necessary, otherwise the compiler can optimise things away.

Note that the `volatile`'s are necessary, otherwise the compiler can optimise things away.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#1582
No description provided.