X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpbd%2Ffloating.h;fp=libs%2Fpbd%2Fpbd%2Ffloating.h;h=f707dc9f5b3a0e941ab980a3903805e489c91c21;hb=5bfa705ff7c601cab13bd4a17997e7376d6c8f96;hp=0000000000000000000000000000000000000000;hpb=f19e7bd238d62de2e4fb80b22146dee53b798852;p=ardour.git diff --git a/libs/pbd/pbd/floating.h b/libs/pbd/pbd/floating.h new file mode 100644 index 0000000000..f707dc9f5b --- /dev/null +++ b/libs/pbd/pbd/floating.h @@ -0,0 +1,53 @@ +/* Taken from + * http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm + * + * Code assumed to be in the public domain. + */ + +#ifndef __libpbd__floating_h__ +#define __libpbd__floating_h__ + +namespace PBD { + +union Float_t +{ + Float_t (float num = 0.0f) : f(num) {} + + // Portable extraction of components. + bool negative() const { return (i >> 31) != 0; } + int32_t raw_mantissa() const { return i & ((1 << 23) - 1); } + int32_t raw_exponent() const { return (i >> 23) & 0xFF; } + + int32_t i; + float f; +}; + +/* Note: ULPS = Units in the Last Place */ + +static inline bool floateq (float a, float b, int max_ulps_diff) +{ + Float_t ua(a); + Float_t ub(b); + + // Different signs means they do not match. + if (ua.negative() != ub.negative()) { + // Check for equality to make sure +0==-0 + if (a == b) { + return true; + } + return false; + } + + // Find the difference in ULPs. + int ulps_diff = abs (ua.i - ub.i); + + if (ulps_diff <= max_ulps_diff) { + return true; + } + + return false; +} + +} /* namespace */ + +#endif /* __libpbd__floating_h__ */