More floating point alternatives

(wizardzines.com)

33 points | by vismit2000 2 days ago

9 comments

  • AlotOfReading 6 hours ago
    Usually, if you know enough about your algorithms to select an appropriate float alternative, you also know enough to fix your float code and that's what you should actually do.

    That said, some of these aren't alternatives. Symbolic computation is a different thing entirely. Interval arithmetic can be built atop floats (e.g. IEEE-1788) and has its own zoo of unintuitive behaviors. BCD is better called a historical artifact than an alternative these days.

    It's really just rationals and decimal floats in this list, which probably don't solve the issues you have if you're considering float alternatives.

    • lelanthran 1 hour ago
      > BCD is better called a historical artifact than an alternative these days.

      It's currently in use all over the world. You can't do a card payment, either in-person or online, without an intermediary using ISO8583.

    • TZubiri 4 hours ago
      You can't "fix" floating point code if you are looking for deterministic answers. You just have to use other data types to handle money or complex mathematical operations like 0.2+0.1, no ifs and buts.
      • AlotOfReading 1 hour ago
        Floats are deterministic, but I get what you mean. Let's discuss what's meant by the result of a complex calculation. 0.1+0.2, or sqrt(2), or whatever.

        1. Do you want your result to exactly encode the answer without rounding error? No fixed precision type can provide this in general, so you're stuck with symbolic approaches. If you can bound things (usually difficult), maybe you can get away with non-symbolic approaches.

        2. Do you want a sensible numeric answer? This is what floats (and many other systems) give you. The definition of "sensible" is inherently tricky here and there's not a definition universally appropriate to every possible computation.

        So let's return to 0.1+0.2=0.3000...1 specifically. There's two common ways to think of an encoded float. One is as the directly encoded value, as you're doing. Another way is to think of it as an interval of real numbers between the next lowest and highest intervals. Under this latter interpretation, it makes sense to discuss shortest decimal string within the interval, 0.3 in this case. There's no ambiguity because each real lives in exactly one interval. This is what algorithms like dragon box do for float to decimal string conversion.

        What decimal floats give you is an encoding that tracks significant digits, where every decimal string exactly corresponds to a midpoint of an interval of reals. They do this at the cost of space, speed, and complexity. You don't get an escape from the fundamental issues of fixed precision types like rounding error, numerical sensitivity, precision loss, etc. I don't think that tradeoff makes sense for most algorithms in most contexts.

        The benefit of sticking with floats is that lots of smart people have spent countless hours trying to give non-experts a "good enough" path through the untamed wilds of numerical analysis, tooling to help them when they get lost, tribal knowledge to point out the edge cases, and it's almost universally supported in hardware. By all means you should go wandering off the trail, but fully understand what you're doing and why beforehand.

      • messe 4 hours ago
        Floating point is deterministic, what are you talking about?

        > You just have to use other data types to handle money or complex mathematical operations like 0.2+0.1

        Such as... decimal floating point.

        • timschmidt 3 hours ago
          > Floating point is deterministic, what are you talking about?

          Order of operations can change a result, for example. I suspect you mean that the algorithm never changes. While op means that mathematical operations which most folks would expect to be reliable are not.

          • messe 2 hours ago
            They're not associative, sure. But that's a very far cry from claiming they're non-deterministic.
  • ashton314 5 hours ago
    Also of interest: Herbie analyzes your math expressions and helps you figure out where FP error accumulates. https://herbie.uwplse.org/demo/

    We use floats as a trade-off between speed and accuracy. IEEE 754 is a very reasonable trade-off for a wide range of applications, but if you can figure out where you need to trade speed to get more accuracy with e.g. one of the methods mentioned here, Herbie's gotcha covered.

    I remember seeing some research about switching between formats, but I don't have anything to cite right now.

  • Panzerschrek 3 hours ago
    In some cases I use binary fixed-point numbers. In certain aspects they are much better than floats - no precision loss happens in addition/subtraction (if no overflow/underflow takes place), additions and subtractions are typically faster (since it's just an integer operation internally), casting from and to integers is also cheap (requires only bit-shift).

    Multiplications are a little bit tricky. Multiplication by an integer is trivial. Multiplication of two fixed point numbers produces the result with the number of fractional binary digits equal to sum of the number of fractional digits in source numbers. The result may be stored in an extended type, truncated down or rounded.

    Divisions work fine too, but sometimes may be slower compared to float types, because CPUs can for some reason do much faster floating-point divisions compared to integer divisions.

    The only disadvantage of fixed-point numbers is that it's required to keep a balance between range and precision carefully. One can't just use some specific precision in the entire codebase, typically precision should be selected for each individual operation.

    • mdspan 50 minutes ago
      Worth noting the gap between floating point vs integer division isn't that bad on newer CPUs these days. On Zen5, for instance, DIVSD has a latency of 13 cycles vs 16 cycles for DIV.
  • timschmidt 4 hours ago
    Oh hey, one of my projects is relevant to an article: https://github.com/timschmidt/hyperreal

    It's an infinite precision exact constructive real with excellent performance characteristics and approximation only at explicitly named lossy export functions.

    Some recent benchmarks: https://github.com/timschmidt/hyperlattice/blob/805d092d1d96...

  • MiroslavPokorny 2 days ago
    Strange the most obvious - fixed point numbers is not mentioned.
  • thebeardisred 4 hours ago
  • klodolph 6 hours ago
    Worth mentioning is storing the logarithm of the number.

    Seen it used in a couple places. Logarithmic depth buffer is one. Yamaha DX7 is another.

    • mtklein 6 hours ago
      That's kind of exactly what floats are. You store the log2 of the number, a bit for its sign, and in what remaining bits you have left some fixed-point scaling between adjacent powers.
      • pkaye 1 hour ago
        Floats are actually rational numbers with denominators of power of 2.

        https://en.wikipedia.org/wiki/Dyadic_rational#In_computing

      • em3rgent0rdr 4 hours ago
        No, that is not what floats are. A logarithmic number system literally just stores the logarithm of a number (and a sign bit) and manipulates it as a logarithm. The significand is 1, always. So multiplication & division are simply addition & subtraction, respectively. But this simplification for multiplication, division, roots, and powers is counterbalanced by more complex addition and subtraction.[1]

        [1] https://en.wikipedia.org/wiki/Logarithmic_number_system

      • mdspan 4 hours ago
        I think they mean storing just an exponent instead of an exponent + mantissa. Makes multiplication much easier to implement.
  • schiffern 2 days ago
    None of the base 10 formats, but the hobby calculation language Frink supports exact rational fractions, arbitrary width bigints (not pictured), intervals arithmetic, and symbolic expressions.

    https://frinklang.org/fsp/frink.fsp?fromVal=new+interval%5B-...

  • joinHNtheysaid 4 hours ago
    [dead]