* [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float
@ 2025-03-24 10:55 Lénárd Szolnoki
2025-04-08 22:25 ` Szabolcs Nagy
0 siblings, 1 reply; 5+ messages in thread
From: Lénárd Szolnoki @ 2025-03-24 10:55 UTC (permalink / raw)
To: musl
Hi,
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
int main() {
const char* const input = "0x1.fffffffffffff8p+1023";
double ret = strtod(input, NULL);
assert(errno == ERANGE);
}
The input is slightly out of range, DBL_MAX is 1.fffffffffffffp+1023 (one fewer binary 1
in the mantissa).
The assert fails with musl libc, passes with glibc.
musl version: 1.2.5 (as shipped in Debian sid)
Regards,
Lénárd Szolnoki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float
2025-03-24 10:55 [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float Lénárd Szolnoki
@ 2025-04-08 22:25 ` Szabolcs Nagy
2025-04-09 10:38 ` Lénárd Szolnoki
0 siblings, 1 reply; 5+ messages in thread
From: Szabolcs Nagy @ 2025-04-08 22:25 UTC (permalink / raw)
To: Lénárd Szolnoki; +Cc: musl
* Lénárd Szolnoki <cpp@lenardszolnoki.com> [2025-03-24 10:55:36 +0000]:
> Hi,
>
> #include <stdlib.h>
> #include <assert.h>
> #include <errno.h>
>
> int main() {
> const char* const input = "0x1.fffffffffffff8p+1023";
> double ret = strtod(input, NULL);
> assert(errno == ERANGE);
> }
>
> The input is slightly out of range, DBL_MAX is 1.fffffffffffffp+1023 (one
> fewer binary 1 in the mantissa).
>
> The assert fails with musl libc, passes with glibc.
this looks valid (might depend on long double
representation).
the overflow threshold is not calculated precisely
for the hexfloat case. __floatscan returns an in
range long double value that is rounded to inf by
strtod, but there is no overflow check there.
i guess hexfloat overflow check should be fixed.
>
> musl version: 1.2.5 (as shipped in Debian sid)
>
> Regards,
> Lénárd Szolnoki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float
2025-04-08 22:25 ` Szabolcs Nagy
@ 2025-04-09 10:38 ` Lénárd Szolnoki
2025-04-09 12:55 ` Szabolcs Nagy
0 siblings, 1 reply; 5+ messages in thread
From: Lénárd Szolnoki @ 2025-04-09 10:38 UTC (permalink / raw)
To: musl; +Cc: nsz
On 08/04/2025 23:25, Szabolcs Nagy wrote:
> * Lénárd Szolnoki <cpp@lenardszolnoki.com> [2025-03-24 10:55:36 +0000]:
>> Hi,
>>
>> #include <stdlib.h>
>> #include <assert.h>
>> #include <errno.h>
>>
>> int main() {
>> const char* const input = "0x1.fffffffffffff8p+1023";
>> double ret = strtod(input, NULL);
>> assert(errno == ERANGE);
>> }
>>
>> The input is slightly out of range, DBL_MAX is 1.fffffffffffffp+1023 (one
>> fewer binary 1 in the mantissa).
>>
>> The assert fails with musl libc, passes with glibc.
>
> this looks valid (might depend on long double
> representation).
Good point, maybe I should have used strtof. Anyway, I am testing on x86_64 Linux, with
80bit long double.
>
> the overflow threshold is not calculated precisely
> for the hexfloat case. __floatscan returns an in
> range long double value that is rounded to inf by
> strtod, but there is no overflow check there.
An other test case is with a different behaviour is
"0x1.fffffffffffff00000000000000000000000000000000000000000000001p+1023"
This is even more slightly larger than DBL_MAX, therefore it should still return inf and
set errno to ERANGE.
For this one strtod returns DBL_MAX. What happens is that this rounds towards the value of
DBL_MAX within long double, and the conversion from long double to double is exact, so it
does not overflow. Sort of a double rounding problem, but at the edge of the range of double.
>
> i guess hexfloat overflow check should be fixed.
>
>>
>> musl version: 1.2.5 (as shipped in Debian sid)
>>
>> Regards,
>> Lénárd Szolnoki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float
2025-04-09 10:38 ` Lénárd Szolnoki
@ 2025-04-09 12:55 ` Szabolcs Nagy
2025-04-09 13:20 ` Lénárd Szolnoki
0 siblings, 1 reply; 5+ messages in thread
From: Szabolcs Nagy @ 2025-04-09 12:55 UTC (permalink / raw)
To: Lénárd Szolnoki; +Cc: musl
* Lénárd Szolnoki <cpp@lenardszolnoki.com> [2025-04-09 11:38:01 +0100]:
> On 08/04/2025 23:25, Szabolcs Nagy wrote:
> > * Lénárd Szolnoki <cpp@lenardszolnoki.com> [2025-03-24 10:55:36 +0000]:
> > > Hi,
> > >
> > > #include <stdlib.h>
> > > #include <assert.h>
> > > #include <errno.h>
> > >
> > > int main() {
> > > const char* const input = "0x1.fffffffffffff8p+1023";
> > > double ret = strtod(input, NULL);
> > > assert(errno == ERANGE);
> > > }
> > >
> > > The input is slightly out of range, DBL_MAX is 1.fffffffffffffp+1023 (one
> > > fewer binary 1 in the mantissa).
> > >
> > > The assert fails with musl libc, passes with glibc.
...
> > the overflow threshold is not calculated precisely
> > for the hexfloat case. __floatscan returns an in
> > range long double value that is rounded to inf by
> > strtod, but there is no overflow check there.
>
> An other test case is with a different behaviour is
> "0x1.fffffffffffff00000000000000000000000000000000000000000000001p+1023"
>
> This is even more slightly larger than DBL_MAX, therefore it should still
> return inf and set errno to ERANGE.
>
in nearest rounding mode i'd expect DBL_MAX.
in upward rounding mode musl seems to return inf.
> For this one strtod returns DBL_MAX. What happens is that this rounds
> towards the value of DBL_MAX within long double, and the conversion from
> long double to double is exact, so it does not overflow. Sort of a double
> rounding problem, but at the edge of the range of double.
there is only a single rounding, and i think that's fine.
> >
> > i guess hexfloat overflow check should be fixed.
> >
> > >
> > > musl version: 1.2.5 (as shipped in Debian sid)
> > >
> > > Regards,
> > > Lénárd Szolnoki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float
2025-04-09 12:55 ` Szabolcs Nagy
@ 2025-04-09 13:20 ` Lénárd Szolnoki
0 siblings, 0 replies; 5+ messages in thread
From: Lénárd Szolnoki @ 2025-04-09 13:20 UTC (permalink / raw)
To: musl; +Cc: Szabolcs Nagy
On 09/04/2025 13:55, Szabolcs Nagy wrote:
> * Lénárd Szolnoki <cpp@lenardszolnoki.com> [2025-04-09 11:38:01 +0100]:
>> On 08/04/2025 23:25, Szabolcs Nagy wrote:
>>> * Lénárd Szolnoki <cpp@lenardszolnoki.com> [2025-03-24 10:55:36 +0000]:
>>>> Hi,
>>>>
>>>> #include <stdlib.h>
>>>> #include <assert.h>
>>>> #include <errno.h>
>>>>
>>>> int main() {
>>>> const char* const input = "0x1.fffffffffffff8p+1023";
>>>> double ret = strtod(input, NULL);
>>>> assert(errno == ERANGE);
>>>> }
>>>>
>>>> The input is slightly out of range, DBL_MAX is 1.fffffffffffffp+1023 (one
>>>> fewer binary 1 in the mantissa).
>>>>
>>>> The assert fails with musl libc, passes with glibc.
> ...
>>> the overflow threshold is not calculated precisely
>>> for the hexfloat case. __floatscan returns an in
>>> range long double value that is rounded to inf by
>>> strtod, but there is no overflow check there.
>>
>> An other test case is with a different behaviour is
>> "0x1.fffffffffffff00000000000000000000000000000000000000000000001p+1023"
>>
>> This is even more slightly larger than DBL_MAX, therefore it should still
>> return inf and set errno to ERANGE.
>>
>
> in nearest rounding mode i'd expect DBL_MAX.
It appears that you are right. I expected DBL_MAX to be the threshold for all rounding
modes, but I double checked the IEEE standard and it seems that for nearest rounding mode
the threshold is exactly my first example.
>
> in upward rounding mode musl seems to return inf.
>
>> For this one strtod returns DBL_MAX. What happens is that this rounds
>> towards the value of DBL_MAX within long double, and the conversion from
>> long double to double is exact, so it does not overflow. Sort of a double
>> rounding problem, but at the edge of the range of double.
>
> there is only a single rounding, and i think that's fine.
>
>
>>>
>>> i guess hexfloat overflow check should be fixed.
>>>
>>>>
>>>> musl version: 1.2.5 (as shipped in Debian sid)
>>>>
>>>> Regards,
>>>> Lénárd Szolnoki
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-04-09 13:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-24 10:55 [musl] strtod doesn't set errno to ERANGE for slightly out-of-range hex float Lénárd Szolnoki
2025-04-08 22:25 ` Szabolcs Nagy
2025-04-09 10:38 ` Lénárd Szolnoki
2025-04-09 12:55 ` Szabolcs Nagy
2025-04-09 13:20 ` Lénárd Szolnoki
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).