Skip to content

Comment on Faster floating point math with Rust's new APIparent

Comments

Rational numbers don't let you do basic things like "measure the distance between two points" (because functions like sqrt or exp aren't defined on rational numbers).

However the floating point types are just binary rationals, so if we took this "can't do basic things" at face value we couldn't do these operations on the floating point types either.

The reason they're so weird is a convenience to the implementation. I am not an EE so I can't tell you how much that saved, but it was a choice, obviously we can't implement the Reals because Almost All Reals aren't even Computable, but I think most software engineers really don't have an appropriate understanding of the floating point types and the result is buggy software.

The main selling point that people tout for using rational numbers over floating-point is their exactness, and the main thing people complain about floating-point is their approximate nature. Introduce the ability to do sqrt on rational numbers, and you somehow have to invent approximation for rational numbers. Choose the nearest representable rational number, and oops, nearly every operation on that rational number could overflow the numerator or denominator, so change that and oops now you've basically reinvented floating-point but worse.

Which is sort of the thing of floating-point: they may be weird, but it kind of turns out that they're ultimately less weird than all of their alternatives, if you try to do anything other than toy examples on them. It's almost like floating-point was designed by people who needed to do a lot of numerical work in computers instead of students in Programming 101!

As somebody who has implemented Hans Boehm's "Towards an API for the Real Numbers" paper I cannot agree that the floating point types are "less weird" than alternatives. They're much faster of course because they're implemented in hardware, but that's hardly surprising.

In my (unpublished) toy calculator I added a mechanism to bring an f32 or f64 into existence and convert it to my Rational type and so that's why I had the exact value of the f32 we call 0.1 to hand earlier. But of course the API goes much further than that. Want to multiply the square root of 40 by the square root of 1000? No problem that's exactly 20. A bright teenager can figure that out, and so can a properly designed API for numbers. The ordinary human activities you talked about of course work just fine in this API, it has historically been how the calculator in an Android phone works for example.

Symbolic approaches also have value in this space.

In both cases, what you do not get is the problem where the programmer mistakenly believes these types will behave like the numbers in school but actually they behave in an entirely different way. You have to go really far off piste, by which point likely the programmer has appreciated that they do not understand what's going on, before you trip on a hazard we cannot manage with this approach - whereas in traditional floating point that happens without them realising.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.