Bug 296791 - powl returns wrong sign
Summary: powl returns wrong sign
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: 15.1-RELEASE
Hardware: amd64 Any
: --- Affects Many People
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-07-14 17:11 UTC by Kenta Kubo
Modified: 2026-07-19 05:41 UTC (History)
1 user (show)

See Also:


Attachments
reproducible example (2.82 KB, text/plain)
2026-07-14 17:11 UTC, Kenta Kubo
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kenta Kubo 2026-07-14 17:11:50 UTC
Created attachment 272844 [details]
reproducible example

C23 ยง7.12.1 p5:

> A floating result overflows if a finite result value with ordinary accuracy would have magnitude
> (absolute value) too large for the representation with full precision in the specified type. A result
> that is exactly an infinity does not overflow. If a floating result overflows and default rounding
> is in effect, then the function returns the value of the macro HUGE_VAL, HUGE_VALF, or HUGE_VALL
> according to the return type, **with the same sign as the correct value of the function.**

However, when an overflow or an underflow occurs in powl, it returns a wrong sign in some patterns.

Wrong patterns:

powl(-3.0L, odd) = inf should be -inf
powl(-1.0L / 3.0L, odd) = 0 should be -0
powl(-3.0L, -odd) = 0 should be -0
powl(-1.0L / 3.0L, -odd) = inf should be -inf

Correct patterns:

powl(3.0L, even) = inf should be inf
powl(INFINITY, even) = inf should be inf
powl(3.0L, odd) = inf should be inf
powl(INFINITY, odd) = inf should be inf
powl(1.0L / 3.0L, even) = 0 should be 0
powl(1.0L / INFINITY, even) = 0 should be 0
powl(1.0L / 3.0L, odd) = 0 should be 0
powl(1.0L / INFINITY, odd) = 0 should be 0
powl(-3.0L, even) = inf should be inf
powl(-INFINITY, even) = inf should be inf
powl(-INFINITY, odd) = -inf should be -inf
powl(-1.0L / 3.0L, even) = 0 should be 0
powl(-1.0L / INFINITY, even) = 0 should be 0
powl(-1.0L / INFINITY, odd) = -0 should be -0
powl(3.0L, -even) = 0 should be 0
powl(INFINITY, -even) = 0 should be 0
powl(3.0L, -odd) = 0 should be 0
powl(INFINITY, -odd) = 0 should be 0
powl(1.0L / 3.0L, -even) = inf should be inf
powl(1.0L / INFINITY, -even) = inf should be inf
powl(1.0L / 3.0L, -odd) = inf should be inf
powl(1.0L / INFINITY, -odd) = inf should be inf
powl(-3.0L, -even) = 0 should be 0
powl(-INFINITY, -even) = 0 should be 0
powl(-INFINITY, -odd) = -0 should be -0
powl(-1.0L / 3.0L, -even) = inf should be inf
powl(-1.0L / INFINITY, -even) = inf should be inf
powl(-1.0L / INFINITY, -odd) = -inf should be -inf

You can easily reproduce the issue with the attached file.

> clang -lm test.c
> ./a.out
Comment 1 Steve Kargl freebsd_committer freebsd_triage 2026-07-19 05:41:44 UTC
Someone grabbed powl() from the CEPHES math library.
I suspect limited testing was performed.