Lumiera  0.pre.03
»edit your freedom«
util-quant.hpp File Reference

Go to the source code of this file.

Description

Utilities for quantisation (grid alignment) and comparisons.

Definition in file util-quant.hpp.

#include <cstdlib>
#include <climits>
#include <cfloat>
#include <cmath>

Classes

struct  IDiv< I >
 helper to treat int or long division uniformly More...
 
struct  IDiv< int >
 
struct  IDiv< long >
 
struct  IDiv< long long >
 

Functions

bool almostEqual (double d1, double d2, unsigned int ulp=2)
 epsilon comparison of doubles. More...
 
template<typename I >
floordiv (I num, I den)
 floor function for integer arithmetics. More...
 
template<typename I >
IDiv< I > floorwrap (I num, I den)
 scale wrapping operation. More...
 
template<typename I >
IDiv< I > iDiv (I num, I den)
 
template<typename I >
constexpr int ilog2 (I num)
 Integral binary logarithm (disregarding fractional part) More...
 

Function Documentation

◆ iDiv()

IDiv<I> util::iDiv ( num,
den 
)
inline
Parameters
densupport type inference and auto typing...

Definition at line 84 of file util-quant.hpp.

References util::iDiv().

Referenced by util::iDiv(), and util::reQuant().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ floordiv()

I util::floordiv ( num,
den 
)
inline

floor function for integer arithmetics.

Unlike the built-in integer division, this function always rounds towards the next smaller integer, even for negative numbers.

Warning
floor on doubles performs way better
See also
UtilFloordiv_test

Definition at line 99 of file util-quant.hpp.

References util::floordiv().

Referenced by util::floordiv().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ floorwrap()

IDiv<I> util::floorwrap ( num,
den 
)
inline

scale wrapping operation.

Quantises the numerator value into the scale given by the denominator. Unlike the built-in integer division, this function always rounds towards the next smaller integer and also relates the remainder (=modulo) to this next lower scale grid point.

Returns
quotient and remainder packed into a struct
See also
UtilFloorwarp_test

Definition at line 121 of file util-quant.hpp.

References util::floorwrap().

Referenced by util::floorwrap().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ almostEqual()

bool util::almostEqual ( double  d1,
double  d2,
unsigned int  ulp = 2 
)
inline

epsilon comparison of doubles.

Remarks
Floating point calculations are only accurate up to a certain degree, and we need to adjust for the magnitude of the involved numbers, since floating point numbers are scaled by the exponent. Moreover, we need to be careful with very small numbers (close to zero), where calculating the difference could yield coarse grained 'subnormal' values.
Parameters
ulpnumber of grid steps to allow for difference (default = 2). Here, a 'grid step' is the smallest difference to 1.0 which can be represented in floating point ('units in the last place')
Warning
don't use this for comparison against zero, rather use an absolute epsilon then.
See also
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
https://en.wikipedia.org/wiki/Unit_in_the_last_place
Todo:
3/2024 seems we have solved this problem several times meanwhile /////////////////////////////////TICKET #1360 sort out floating-point rounding and precision

Definition at line 152 of file util-quant.hpp.

References util::almostEqual().

Referenced by util::almostEqual().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ilog2()

constexpr int util::ilog2 ( num)
inline

Integral binary logarithm (disregarding fractional part)

Returns
index of the largest bit set in num; -1 for num==0
Todo:
C++20 will provide std::bit_width(i) — run a microbenchmark!
Remarks
The implementation uses an unrolled loop to break down the given number in a logarithmic search, subtracting away the larger powers of 2 first. Explained 10/2021 by user «ToddLehman» in this stackoverflow.
Note
Microbenchmarks indicate that this function and std::ilogb(double) perform in the same order of magnitude (which is surprising). This function gets slightly faster for smaller data types. The naive bitshift-count implementation is always significantly slower (8 times for int64_t, 1.6 times for int8_t)
See also
Rational_test::verify_intLog2()
ZoomWindow_test

Definition at line 180 of file util-quant.hpp.

References util::ilog2().

Referenced by util::ilog2(), and Rational_test::verify_intLog2().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: