5 ms·
Show HN: Floating point arithmetic types in C++ for any size and any base
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.
- a_t48 2y agoHave nothing to say other than - neat!
- seg_fault 2y agoThank you :)
- fuhsnn 2y agoFor "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 https://ajxs.me/blog/Yamaha_DX7_Technical_Analysis.html
- badmintonbaseba 2y agoPossibly 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.
- seg_fault 2y agoActually 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/58f9effbe6c13ab334b05a956ec885edeac89fac/fas/float.hpp#L27 https://github.com/clemensmanert/fas/blob/58f9effbe6c13ab334...
- Archit3ch 2y agoCan you go in the other direction? Higher exponent and mantissa than regular float/double?
- seg_fault 2y agoSure. 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.
- badmintonbaseba 2y agoNice! > 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/p3375r1.html 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.
- seg_fault 2y agoRounding: 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.
- badmintonbaseba 2y agoBy 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.
- seg_fault 2y agoI 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 :)
- codr7 2y agoHere 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 https://github.com/codr7/claes/blob/main/src/claes/f64.hpp
- listeria 2y agoConsider 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_fundamental https://en.cppreference.com/w/cpp/types/is_floating_point 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_arithmetic https://en.cppreference.com/w/cpp/types/is_scalar https://en.cppreference.com/w/cpp/types/is_scalar https://en.cppreference.com/w/cpp/types/is_object https://en.cppreference.com/w/cpp/types/is_object
- seg_fault 2y agoI don't get what you mean. I thought they specify how the type can be used?
- secondcoming 2y agoTechnically, you're not supposed to add your own specialisations to the `std` namespace
- pmalynin 2y agoIn 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
- rurban 2y agoIt's copyrighted so I should not even look at it, and therefore not comment on it.
- recursive 2y agoAnd yet...
- rurban 2y agoThe API looks fine, well
- syockit 2y agoIt's copyrighted, but nothing stops you from looking at it. It's akin to looking a t a mural painted at someone's house. You can also comment as long as you don't post snippets of the code (except for when fair use is applicable).
- rurban 2y agoLegally yes, but in reality not. In most companies or projects legal tells me not to look at it all, esp. the FSF. I can look at the API, but not the implementation. That's why it's called https://en.wikipedia.org/wiki/Clean-room_design https://en.wikipedia.org/wiki/Clean-room_design.
- dahart 2y agoAll creative works are copyrighted by default in the U.S. and any countries adhering to the Berne convention, unless copyrights are explicitly waived (which is not always an option). This is true regardless of what copyright notices exist, so by that standard you shouldn’t look at or comment on anything. ;) But, it’s legal to look at something copyrighted, you just can’t copy & distribute it. Just curious, did you mean that it lacks an open source license and you only look at open source, or was this just a joke that went sideways, or something else?
- seg_fault 2y agoRemoved it.
- skissane 2y agoNo LICENSE. Have you thought about adding one?
- seg_fault 2y agoSomebody wants to use it? :D I thought about something like where people can use it but have to make changed public. I am just curious, what should be changed. But I dont think there is actually a real world use case.
- zokier 2y agoSounds like you prefer copyleft licenses. I suggest MPL-2.0 or some variety of (L)GPL as they are the most well-known ones.
- nly 2y agoHow does this compare to Boost.Multiprecision, which works well with Boost.Math? https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/do... https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/do...
- seg_fault 2y agoMy type is a bit simpler. But I think the approach is the same. After all, boost's type has much more math functions implemented. I don't have exp, sqrt...
- amelius 2y agoIsn't this in libgmp already? https://gmplib.org/ https://gmplib.org/
- Archit3ch 2y agoGMP doesn't do arbitrary exponents.
- amelius 2y agoIndeed, thanks.
- Archit3ch 2y agoSlight correction, while the exponent is indeed fixed, it is larger than a f32/f64 exponent: https://gmplib.org/manual/Floating_002dpoint-Functions https://gmplib.org/manual/Floating_002dpoint-Functions However, this is not exposed in all GMP wrappers.
- seg_fault 2y agoIf I understand this correctly GMP has a flexible mantissa with no limitations during runtime. In fas you have to specify the sizes (of mantissa and exponent) during compile time. So the size of this type is fixed. Thus, there is no heap involved.
- account42 2y ago> std::numeric_limits<fas::Float<std::int16_t, std::int8_t>>::MAX() Surely you mean ::max()? > is_fundamental<int16_t, int16_t>::value et al. Besides the undefined behavior issue mentioned by others, none of these are syntactially correct. > #include "fas/stream.hpp> Ok then... > The Stl's std::numeric_limits is required the limits of the specified types for mantissa and exponent. Missing a word? Also, the STL [0] does not have std::numeric_limits, perhaps you mean the C++ standard library (or stdlib for short). [0] https://en.wikipedia.org/wiki/Standard_Template_Library https://en.wikipedia.org/wiki/Standard_Template_Library
- ttoinou 2y agoWaiting for someone to implement a mandelbrot zoom with that (: