logoalt Hacker News

No portable way to detect string-to-float conversion errors in standard C

58 points • by signa11 • last Saturday at 3:39 PM • 77 comments • view on HN

Comments

Joker_vD • today at 6:00 AM

It's quite astonishing how the historical inability of commonly used programming languages (from FORTRAN all the way to, say, Java/C#) to ergonomically return two values from a function call has caused people to invent all kinds of insane APIs/contracts.

    [double x, errno_t errno] = strtod(s, nullptr);
    if (errno != 0) {
        // ...
    }

    [x, _] = strtod(s, nullptr);  // When you're certain the error is impossible or just don't care
Instead, we're stuck with "check if the return value is -1 and if it is, check the global variable errno" at best, and with "the function doesn't really reliably reports its errors so don't feed it malformed data, idc" at worst.
➕ show 13 replies
Panzerschrek • today at 5:36 AM

C number parsing functions are fundamentally broken, since they are locale-dependend. There are many bugs when one parses a number assuming it has decimal point, but later on systems with locale different from one used on developer's machine it may be suddenly comma instead of point. So, one should avoid using them almost always and use std::from_chars (available in new C++ versions) or some other thirdparty library.

➕ show 2 replies
Lerc • today at 8:47 PM

When I was writing some ASM for a microcontroller to do string <--> float conversion, I could find almost nothing on how to best perform the operations.

There were essentially three ways to do it. Muddle through with a naive implementation. Look at the ASM of an old 8-bit machine. The final category was the by far the most dominant suggestion, to the point that anything else is almost like lost knowledge now. That solution was to use the C standard functions.

It seems like this is a sufficiently unpleasant task that as soon as anyone didn't absolutely have to do it all themselves, the punted to a black box solution.

There's probably something to be said there about the plethora of hobbiest 3d engines in comparison.

gucci-on-fleek • today at 7:53 AM

> the linux man pages for these functions literally don't mention this at all

> the fact that the man page never makes any note of this being an extension ([…]) is really notable to me.

> this is completely undocumented on the linux man page.

The Linux man page maintainers are really friendly in my experience, so it's probably worth reporting this to them [0] [1].

[0]: https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/...

[1]: https://lore.kernel.org/linux-man/

chasil • today at 4:45 AM

IEEE-754 is a harsh mistress.

https://en.wikipedia.org/wiki/IEEE_754

➕ show 1 reply
RossBencina • today at 7:59 AM

For a long time Microsoft's strtod implementation was broken, I'd think most people would be using netlib or one of the newer algorithms.

https://www.exploringbinary.com/visual-c-plus-plus-strtod-st...

https://lemire.me/blog/2026/02/01/converting-floats-to-strin...

Kevin_Flynn • today at 11:32 AM

> No portable way to detect string-to-float conversion errors in standard C

There isn't just 1 standard C, theres many. AI says theres 5.

There are 5 major ISO C standards: C90, C99, C11, C17/C18, and C23. C89 is essentially the same standard as C90 under its ANSI name, and C95 was an amendment rather than a separate major edition. The latest is C23.

POSIX, as you know, stands for "Portable Operating System Interface."

> posix doesn't give a shit about math_errhandling; it always requires the implementation to set errno if overflow or underflow occurs.

So, POSIX, the "Portable" interface, specifies that underflow/overflow errors are always reported.

The problem seems to be in the headline, not the spec.

j16sdiz • today at 4:23 AM

yes. that's why many number crunching app ships / vendors their own math library

anitil • today at 4:52 AM

Even putting aside the ugliness of errno, this is pretty bad. I'm at the point with libc where I try to use as little of it as I can, though I'm not writing a lot of C these days

➕ show 1 reply
kazinator • today at 1:40 PM

Don't forget locale! If you're in the wrong locale strtod("3,4", ...) may return 3.4, etc.

oso2k • today at 7:07 AM

Sometimes I wish we could get to a timeline where the FPU format standards have something like Crockford’s DEC64 end up winning or evolving into the prevailing standard. Simpler & consistent math ought not to be this hard.

https://www.crockford.com/dec64.html

TZubiri • today at 5:07 AM

" Dinesh: I said I would do DRM you would do error handling.

Gilfoyle: Anything to do with errors is more your vibe"

https://www.youtube.com/watch?v=oyVksFviJVE&t=49

Oh, this one is easy.

Just don't make the errors, then you don't have to detect them.

When your app stops issuing these errors, then you won't have to write blog posts complaining that someone elses code can't handle your errors.

Definitely you should never be converting strings to floats ever anyways, see how I'm going on a limb here without any knowledge of your application, but then you know that I'm right because there's no reason why you would ever do that?

CamperBob2 • today at 4:48 AM

     if (sscanf(string,"%lf",&foo) != 1) 
        { 
        bad_float(); 
        }
This has the benefit of handling scientific notation, too, which some of the other CRTL functions inexplicably do not.

For extra reassurance, initialize foo to NaN or DBL_MAX or something, and verify that it is no longer equal to that value.

➕ show 3 replies