Lumiera
0.pre.03
»edit your freedom«
|
Go to the source code of this file.
Rational number support, based on boost::rational
.
As an extension to integral arithmetics, rational numbers can be defined as a pair (numerator, denominator); since most calculations imply multiplication by common factors, each calculation will be followed by normalisation to greatest common denominator, to keep numbers within value range. Obviously, this incurs a significant performance penalty — while on the other hand allowing for lossless computations on fractional scales, which can be notoriously difficult to handle with floating point numbers. The primary motivation for using this number format is for handling fractional time values properly, e.g 1/30 sec or 1/44100 sec.
The underlying implementation from boost::rational can be parametrised with various integral data types; since our time handling is based on 64bit integers, we mainly use the specialisation boost::rational<int64_t>
.
rational_cast<NUM> (fraction)
is necessary, which performs the division of numerator/denominator
in the target value domain.While the always precise results of integral numbers might seem compelling, the danger of numeric overflow is significantly increased by fractional computations. Most notably, this danger is not limited to large numbers. Adding two fractional number requires multiplications with both denominators, which can overflow easily. Thus, for every given fractional number, there is a class of »dangerous counterparts« which can not be added without derailing the computation, leading to arbitrary wrong results without detectable failure. And these problematic counterparts are distributed over the whole valid numeric range. To give an extreme example, any numbers of the form n / INT_MAX
can not be added or subtracted with any other rational number > 1, while being themselves perfectly valid and representable.
Definition in file rational.hpp.
#include "lib/integral.hpp"
#include "lib/util-quant.hpp"
#include <cmath>
#include <limits>
#include <stdint.h>
#include <boost/rational.hpp>
Typedefs | |
using | Rat = boost::rational< int64_t > |
Functions | |
bool | can_represent_Product (int64_t a, int64_t b) |
bool | can_represent_Product (Rat a, Rat b) |
bool | can_represent_Sum (Rat a, Rat b) |
util::Rat | operator""_r (ullong num) |
user defined literal for constant rational numbers. More... | |
int64_t | reQuant (int64_t num, int64_t den, int64_t u) |
Re-Quantise a number into a new grid, truncating to the next lower grid point. More... | |
Rat | reQuant (Rat src, int64_t u) |
re-Quantise a rational number to a (typically smaller) denominator. More... | |
|
inline |
Re-Quantise a number into a new grid, truncating to the next lower grid point.
num | the count in old grid-steps (#den) or the numerator |
den | the old quantiser or the denominator of a fraction |
u | the new quantiser or the new denominator to use |
Definition at line 120 of file rational.hpp.
References util::iDiv(), and util::reQuant().
Referenced by util::reQuant().
|
inline |
re-Quantise a rational number to a (typically smaller) denominator.
u | the new denominator to use |
Definition at line 150 of file rational.hpp.
References util::reQuant().
|
inline |
user defined literal for constant rational numbers.
Definition at line 165 of file rational.hpp.