| Home | Libraries | People | FAQ | More

#### cpp_bin_float

`#include <boost/multiprecision/cpp_bin_float.hpp>`

    namespace boost{ namespace multiprecision{

    enum digit_base_type
    {
       digit_base_2 = 2,
       digit_base_10 = 10
    };

    template <unsigned Digits, digit_base_type base = digit_base_10, class Allocator = void, class Exponent = int, ExponentMin = 0, ExponentMax = 0>
    class cpp_bin_float;

    typedef number<cpp_bin_float<50> > cpp_bin_float_50;
    typedef number<cpp_bin_float<100> > cpp_bin_float_100;

    typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, std::int16_t, -126, 127>, et_off>         cpp_bin_float_single;
    typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, std::int16_t, -1022, 1023>, et_off>       cpp_bin_float_double;
    typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, std::int16_t, -16382, 16383>, et_off>     cpp_bin_float_double_extended;
    typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, std::int16_t, -16382, 16383>, et_off>    cpp_bin_float_quad;
    typedef number<backends::cpp_bin_float<237, backends::digit_base_2, void, std::int32_t, -262142, 262143>, et_off>  cpp_bin_float_oct;

    }} // namespaces

The `cpp_bin_float` back-end is used in conjunction with `number`: It acts as an entirely C++ (header only and dependency free) floating-point number type that is a drop-in replacement for the native C++ floating-point types, but with much greater precision.

Type `cpp_bin_float` can be used at fixed precision by specifying a non-zero `Digits` template parameter. The typedefs `cpp_bin_float_50` and `cpp_bin_float_100` provide arithmetic types at 50 and 100 decimal digits precision respectively.

Optionally, you can specify whether the precision is specified in decimal digits or binary bits - for example to declare a `cpp_bin_float` with exactly the same precision as `double` one would use `number<cpp_bin_float<53, digit_base_2> >`. The typedefs `cpp_bin_float_single`, `cpp_bin_float_double`, `cpp_bin_float_quad`, `cpp_bin_float_oct` and `cpp_bin_float_double_extended` provide software analogues of the IEEE single, double, quad and octuple float data types, plus the Intel-extended-double type respectively. Note that while these types are functionally equivalent to the native IEEE types, but they do not have the same size or bit-layout as true IEEE compatible types.

Normally `cpp_bin_float` allocates no memory: all of the space required for its digits are allocated directly within the class. As a result care should be taken not to use the class with too high a digit count as stack space requirements can grow out of control. If that represents a problem then providing an allocator as a template parameter causes `cpp_bin_float` to dynamically allocate the memory it needs: this significantly reduces the size of `cpp_bin_float` and increases the viable upper limit on the number of digits at the expense of performance. However, please bear in mind that arithmetic operations rapidly become very expensive as the digit count grows: the current implementation really isn't optimized or designed for large digit counts. Note that since the actual type of the objects allocated is completely opaque, the suggestion would be to use an allocator with `void` `value_type`, for example: `number<cpp_bin_float<1000, digit_base_10, std::allocator<void> > >`.

The final template parameters determine the type and range of the exponent: parameter `Exponent` can be any signed integer type, but note that `MinExponent` and `MaxExponent` can not go right up to the limits of the `Exponent` type as there has to be a little extra headroom for internal calculations. You will get a compile time error if this is the case. In addition if MinExponent or MaxExponent are zero, then the library will choose suitable values that are as large as possible given the constraints of the type and need for extra headroom for internal calculations.

There is full standard library and `numeric_limits` support available for this type.

Things you should know when using this type:

- Default constructed `cpp_bin_float`s have a value of zero.
- The radix of this type is 2, even when the precision is specified as decimal digits.
- The type supports both infinities and NaNs. An infinity is generated whenever the result would overflow, and a NaN is generated for any mathematically undefined operation.
- There is a `std::numeric_limits` specialisation for this type.
- Any `number` instantiated on this type, is convertible to any other `number` instantiated on this type - for example you can convert from `number<cpp_bin_float<50> >` to `number<cpp_bin_float<SomeOtherValue> >`. Narrowing conversions round to nearest and are `explicit`.
- Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted as a valid floating-point number.
- All arithmetic operations are correctly rounded to nearest. String conversions and the `sqrt` function are also correctly rounded, but transcendental functions (sin, cos, pow, exp etc) are not.

###### cpp_bin_float example:

    #include <boost/multiprecision/cpp_bin_float.hpp>
    #include <boost/math/special_functions/gamma.hpp>

    #include <iostream>

    int main()
    {
       using namespace boost::multiprecision;

       // Operations at fixed precision and full numeric_limits support:
       cpp_bin_float_100 b = 2;
       std::cout << std::numeric_limits<cpp_bin_float_100>::digits << std::endl;
       std::cout << std::numeric_limits<cpp_bin_float_100>::digits10 << std::endl;

       // We can use any C++ std lib function, lets print all the digits as well:
       std::cout << std::setprecision(std::numeric_limits<cpp_bin_float_100>::max_digits10)
          << log(b) << std::endl; // print log(2)

       // We can also use any function from Boost.Math:
       std::cout << boost::math::tgamma(b) << std::endl;
       // These even work when the argument is an expression template:
       std::cout << boost::math::tgamma(b * b) << std::endl;

       // And since we have an extended exponent range we can generate some really large
       // numbers here (4.0238726007709377354370243e+2564):
       std::cout << boost::math::tgamma(cpp_bin_float_100(1000)) << std::endl;
       return 0;
    }