mirror of
https://github.com/boostorg/multiprecision.git
synced 2025-05-12 14:01:48 +00:00
BOOST_STATIC_ASSERT BOOST_STATIC_CONST boost::enable_if/disable_if Changed many traits class usages from boost:: to std::.
93 lines
5.3 KiB
Plaintext
93 lines
5.3 KiB
Plaintext
[/
|
|
Copyright 2011 - 2020 John Maddock.
|
|
Copyright 2013 - 2019 Paul A. Bristow.
|
|
Copyright 2013 Christopher Kormanyos.
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt).
|
|
]
|
|
|
|
[section:cpp_bin_float 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.
|
|
|
|
[h5 cpp_bin_float example:]
|
|
|
|
[cpp_bin_float_eg]
|
|
|
|
[endsect]
|