mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-01-27 07:02:10 +00:00
84 lines
3.4 KiB
Plaintext
84 lines
3.4 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:mixed Mixed Precision Arithmetic]
|
|
|
|
Mixed precision arithmetic is fully supported by the library.
|
|
|
|
There are two different forms:
|
|
|
|
* Where the operands are of different precision.
|
|
* Where the operands are of the same precision, but yield a higher precision result.
|
|
|
|
[h4 Mixing Operands of Differing Precision]
|
|
|
|
If the arguments to a binary operator are of different precision, then the operation is allowed
|
|
as long as there is an unambiguous implicit conversion from one argument type to the other.
|
|
In all cases the arithmetic is performed "as if" the lower precision type is promoted to the
|
|
higher precision type before applying the operator. However, particular backends may optimise
|
|
this and avoid actually creating a temporary if they are able to do so.
|
|
|
|
For example:
|
|
|
|
mpfr_float_50 a(2), b;
|
|
mpfr_float_100 c(3), d;
|
|
static_mpfr_float_50 e(5), f;
|
|
mpz_int i(20);
|
|
|
|
d = a * c; // OK, result of operand is an mpfr_float_100.
|
|
b = a * c; // Error, can't convert the result to an mpfr_float_50 as it will lose digits.
|
|
f = a * e; // Error, operator is ambiguous, result could be of either type.
|
|
f = e * i; // OK, unambiguous conversion from mpz_int to static_mpfr_float_50
|
|
|
|
[h4 Operands of the Same Precision]
|
|
|
|
Sometimes you want to apply an operator to two arguments of the same precision in
|
|
such a way as to obtain a result of higher precision. The most common situation
|
|
occurs with fixed precision integers, where you want to multiply two N-bit numbers
|
|
to obtain a 2N-bit result. This is supported in this library by the following
|
|
free functions:
|
|
|
|
template <class ResultType, class Source1 class Source2>
|
|
ResultType& add(ResultType& result, const Source1& a, const Source2& b);
|
|
|
|
template <class ResultType, class Source1 class Source2>
|
|
ResultType& subtract(ResultType& result, const Source1& a, const Source2& b);
|
|
|
|
template <class ResultType, class Source1 class Source2>
|
|
ResultType& multiply(ResultType& result, const Source1& a, const Source2& b);
|
|
|
|
These functions apply the named operator to the arguments ['a] and ['b] and store the
|
|
result in ['result], returning ['result]. In all cases they behave "as if"
|
|
arguments ['a] and ['b] were first promoted to type `ResultType` before applying the
|
|
operator, though particular backends may well avoid that step by way of an optimization.
|
|
|
|
The type `ResultType` must be an instance of class `number`, and the types `Source1` and `Source2`
|
|
may be either instances of class `number` or native integer types. The latter is an optimization
|
|
that allows arithmetic to be performed on native integer types producing an extended precision result.
|
|
|
|
For example:
|
|
|
|
[mixed_eg]
|
|
|
|
Produces the output:
|
|
|
|
[mixed_output]
|
|
|
|
[h4 Backends With Optimized Mixed Precision Arithmetic]
|
|
|
|
The following backends have at least some direct support for mixed-precision arithmetic,
|
|
and therefore avoid creating unnecessary temporaries when using the interfaces above.
|
|
Therefore when using these types it's more efficient to use mixed-precision arithmetic,
|
|
than it is to explicitly cast the operands to the result type:
|
|
|
|
__mpfr_float_backend, __mpf_float, __cpp_int.
|
|
|
|
[endsect] [/section:mixed Mixed Precision Arithmetic]
|