Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
rational.hpp File Reference

Rational number support, based on boost::rational. More...

Go to the source code of this file.

Description

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>.

Note
all compatible integral types can be automatically converted to rational numbers, which is a lossless conversion. The opposite is not true: to get a "ordinary" number — be it integral or floating point — an explicit conversion using rational_cast<NUM> (fraction) is necessary, which performs the division of numerator/denominator in the target value domain.

Perils of fractional arithmetics

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.

rule of thumb
Use fractional arithmetics only where it is possible to control the denominators involved. Never use them for computations drawing from arbitrary (external) input.
See also
Rational_test
zoom-window.hpp
timevalue.hpp

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>

Namespaces

namespace  util
 

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)
 
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.
 
Rat reQuant (Rat src, int64_t u)
 re-Quantise a rational number to a (typically smaller) denominator.
 
util::Rat operator""_r (ullong num)
 user defined literal for constant rational numbers.
 

Function Documentation

◆ operator""_r()

util::Rat operator""_r ( ullong  num)
inline

user defined literal for constant rational numbers.

Rat twoThirds = 2_r/3;

Definition at line 165 of file rational.hpp.