Re: Questions about powf inaccuracies on ARM Cortex-M7

Fabian Schriever <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
Hello Matthias,

let's start with ef_pow.c and sf_pow.c, they are the reason this change 
is likely to not matter to you. sf_pow.c is the version of the pow 
function that the nice people from Arm Ltd. especially added for ARM 
users, while ef_pow.c (called through wf_pow.c) is the older version and 
still in use by several other architectures. So yes, they are different 
implementations. Which version is used depends on the define 
__OBSOLETE_MATH, which has most likely been set by your toolchain.

Now for the value issue. It's likely that Bruce Evans used the hex 
values directly as an input for his tests (same for us), so the 
0.9999999 is likely to be a typo as it (correctly) converts to 3F7FFFFE 
on your system. And with a different input you, of course, get a 
different output. I'd suggest you use 0.99999994 if you still want to 
run your test.

Best regards,
Fabian


Am 16.05.2025 um 12:01 schrieb Matthias Weber:
> Hi all,
>
> first of all thanks for maintaining newlib and for providing help on 
> the mailing list. Keep up your nice work!
>
> I usually do not look behind the scenes of a standard library, but 
> reading about "fixes to powf" in "Major changes in newlib version 
> 4.5.0" in the NEWS file caught my attention.
>
> I've tried to understand what this means and whether it affects 
> calculations on ARM Cortex-M7. I am asking for some guidance here - 
> maybe you can enlighten me.
>
> Background/context:
> In thread https://sourceware.org/pipermail/newlib/2024/021294.html, 
> Fabian submitted powf inaccuracy patches (taken from FreeBSD and 
> authored by Bruce Evans).
> I am using Arm GNU Toolchain 11.3.rel1 (released on 08.08.2022) for an 
> ARM Cortex-M7 based uC which seems to ship a prebuilt 
> newlib/newlib-nano. I am linking with newlib-nano.
> The toolchain's release notes s tates commit 
> bfee9c6ab0c3c9a5742e84509d01ec6472aa62c4 of the newlib-cygwin git repo.
> I've tracked this down and it seems that this is no specific release 
> version from December but rather an intermediate snapshot between 
> versions 4.3.0 (2023-01-20) and 4.2.0 (2021-12-31). So this version is 
> "quite old" and does not cover the above mentioned major change of 
> newlib version 4.5.0.
> I am trying to find out whether upgrading to newlib-nano 4.5.0 may 
> improve accuracy or if I am not affected at all (as the messages 
> explicitely mention i386).
>
> For a quick test, I've compiled and ran the following code on my 
> target to see if I could reproduce the issue:
>
> ```
>     // Test powf functionality for inaccuracies
>     float x = -1.1;
>     float y = 101.0;
>     float z;
>     z = powf(x, y);
>
>     float a = 0.9999999;
>     float b = -2.9999995;
>     float c;
>     c = powf(a, b);
> ```
>
> I then took a look at the actual values using GDB:
>
> ```
> (gdb) p/x x
> $30 = 0xbf8ccccd
> (gdb) p/x y
> $31 = 0x42ca0000
> (gdb) p/x z
> $32 = 0xc66cdad4
> (gdb) p z
> $86 = -15158.707
>
> (gdb) p/x a
> $33 = 0x3f7ffffe
> (gdb) p/x b
> $34 = 0xc03ffffe
> (gdb) p c
> $87 = 1.00000036
> (gdb) p/x c
> $35 = 0x3f800003
> ```
>
> So the first calculation seems to yield the correct result (variable 
> z) whereas the second one seems to be wrong (variable c) - when 
> comparing to the results shared in the mailing list:
> The wrong result there was 1.0000002 (hex 3F800002) whereas it was 
> described to should have yielded 1.0000001 (hex 3F800001).
> As you can see, I even got 1.00000036 (hex 0x3f800003) -- which is 
> even further off.
>
> Having taken a second closer look, revealed that the input variable a 
> is also slightly off: 0x3f7ffffe (in the mailing list: hex 3F7FFFFF).
>
> ```
> (gdb) p a
> $124 = 0.999999881
> ```
> Why does my compiler(?) treat the literal floating-point literal 
> differently?
>
> Unfortunately, I was unable to step into powf as GDB claims:
> /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libm/common/sf_pow.c: 
> No such file or directory.
>
> I was unable to replace/fix the search path/ redirect it to the local 
> checkout of the newlib-cygwin repo. This is beyond my GDB skills for 
> now. Maybe you can give me a hint here.
>
> As the submitted patch affects newlib/libm/math/ef_pow.c, I was 
> wondering if I was affected at all because you can see that GDB tried 
> to search in a different file: newlib/libm/common/sf_pow.c
>
> Are ef_pow.c and sf_pow.c related or are they completely different 
> implementations and so the patch does not help me anyways?
> "sf" seems to stand for "Single-precision", what does the "ef" in 
> ef_pow.c stand for?
> What am I missing?
>
> Many thanks,
> Matthias
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.