Most active commenters
  • seg_fault(7)
  • badmintonbaseba(4)

65 points seg_fault | 23 comments | | HN request time: 1.963s | source | bottom

Since there is so much interest on HN in floats lately and their software implementations, I wanted to show mine. It has no use and is just for teaching me floats and C++. Give me your thoughts.
1. a_t48 ◴[] No.41907900[source]
Have nothing to say other than - neat!
replies(1): >>41908365 #
2. fuhsnn ◴[] No.41907946[source]
For "any size" I was kind of expecting arbitrary sized mantissa/exponent, can be useful for emulating weird DACs, for example, 12-bit mantissa and 3-bit exponent[1].

[1] https://ajxs.me/blog/Yamaha_DX7_Technical_Analysis.html

replies(2): >>41908010 #>>41908315 #
3. badmintonbaseba ◴[] No.41907988[source]
Nice!

> TODO: (configurable) rounding support

What's the default rounding mode? Round to nearest even?

You might be interested in https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p33... too, which is a recent paper for introducing reproducible floating point to C++.

Very small floating point types can be handy for exhaustive testing of floating point function templates, especially ones that take multiple arguments. Walking over all floating point values for a small type often finds most if not all corner cases that can manifest with a floating point type of any size.

replies(1): >>41908252 #
4. badmintonbaseba ◴[] No.41908010[source]
Possibly could be combined with C23's _BitInt(N) for the template arguments? I think it's available in clang as a C++ extension.

edit: or I guess you could have your own Tmantissa and Texponent types as custom classes that correctly model _BitInt(N), they don't seem to be required to be builtin integral types.

5. codr7 ◴[] No.41908190[source]
Here is an example of the other end of the spectrum that I've used a couple of times: very simple fixpoints.

https://github.com/codr7/claes/blob/main/src/claes/f64.hpp

6. listeria ◴[] No.41908198[source]
Consider dropping the specializations for the type traits, given that it's undefined behavior:

https://en.cppreference.com/w/cpp/types/is_fundamental

https://en.cppreference.com/w/cpp/types/is_floating_point

https://en.cppreference.com/w/cpp/types/is_arithmetic

https://en.cppreference.com/w/cpp/types/is_scalar

https://en.cppreference.com/w/cpp/types/is_object

replies(2): >>41908384 #>>41909333 #
7. seg_fault ◴[] No.41908252[source]
Rounding: actually it just cuts off. I have not spent much time to think about how to specify and implement the different rounding modes. Maybe some day...

Thanks for the hint to the paper. I also faced these issues. Thus, I provided a constructor which accepts mantissa and exponent as values. Very handy for the unittests.

replies(1): >>41908733 #
8. seg_fault ◴[] No.41908315[source]
Actually you can specify the numeric limits of the mantissa and the exponent. They can be specified as template arguments[0]. So you could do:

      Float<uint8_t, // type of the mantissa
            uint8_t, // type of the exponent
            0,       // lowest possible value of the mantissa
            4095,    // highest possible value of the mantissa
            0,       // lowest possible value of the exponent
            7>       // highest possible value of the exponent
The Float then simulates an unsigned 12bit mantissa and a 3bit exponent. Sure it still takes 16 bytes. But you could create a union with bitfields where you shrink that even further.

[0] https://github.com/clemensmanert/fas/blob/58f9effbe6c13ab334...

replies(1): >>41908690 #
9. seg_fault ◴[] No.41908365[source]
Thank you :)
10. seg_fault ◴[] No.41908384[source]
I don't get what you mean. I thought they specify how the type can be used?
replies(2): >>41908617 #>>41908663 #
11. secondcoming ◴[] No.41908617{3}[source]
Technically, you're not supposed to add your own specialisations to the `std` namespace
replies(1): >>41908849 #
12. badmintonbaseba ◴[] No.41908663{3}[source]
The cppreference page says:

> If the program adds specializations for std::is_fundamental or std::is_fundamental_v, the behavior is undefined.

This is an oversimplification. The actual rule is https://eel.is/c++draft/library#namespace.std-2 .

> the specialization meets the standard library requirements for the original template.

For is_fundamental<YourClassType> it means that is_fundamental<YourClassType>::value must be false, as YourClassType is not a fundamental type, as defined in https://eel.is/c++draft/basic.fundamental#17 .

Some traits are just not designed to be customization points.

13. Archit3ch ◴[] No.41908690{3}[source]
Can you go in the other direction? Higher exponent and mantissa than regular float/double?
replies(1): >>41908761 #
14. badmintonbaseba ◴[] No.41908733{3}[source]
By cutting off do you mean that it correctly rounds towards zero? Maybe you can implement rounding to closest by just doing the calculation in a one digit wider mantissa with rounding to zero and observing the last digit, at least for an even base. It won't be rounding to even though, but for that a 2 digit wider mantissa is probably enough.

Rounding to nearest with an odd base doesn't seem to be as straightforwardly implementable from rounding to zero calculations at a higher precision.

replies(1): >>41908790 #
15. seg_fault ◴[] No.41908761{4}[source]
Sure.

    Float<int64_t, int64_t>
Gives you a signed Mantissa with 64 bit and a signed Exponent with 64bit. Since there are numeric limits for int64_t available, Float knows the max and the min value.

You could get even bigger ranges for Float by implementing your own big integer type.

16. seg_fault ◴[] No.41908790{4}[source]
I remember that I tried that some time ago. Especially the multiplication was tough, but I can not recall where I gave up. When I find some time, I will pick it up again :)
17. pmalynin ◴[] No.41908849{4}[source]
In general this isn’t true (i guess it is in this specific context). For example I believe it’s totally expected to specialize std hash
replies(1): >>41909632 #
18. rurban ◴[] No.41908916[source]
It's copyrighted so I should not even look at it, and therefore not comment on it.
19. skissane ◴[] No.41909252[source]
No LICENSE. Have you thought about adding one?
20. dataflow ◴[] No.41909333[source]
Why is std::is_object even specialized here? Isn't it always true regardless?
21. tyleo ◴[] No.41909632{5}[source]
I’ve also done this with hash… though given the footguns scattered about, I wouldn’t be surprised if it broke the spec.
22. nly ◴[] No.41909728[source]
How does this compare to Boost.Multiprecision, which works well with Boost.Math?

https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/do...

https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/do...