JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_MathsFunctions.h
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
27/*
28 This file sets up some handy mathematical typdefs and functions.
29*/
30
31//==============================================================================
32// Definitions for the int8, int16, int32, int64 and pointer_sized_int types.
33
35using int8 = signed char;
37using uint8 = unsigned char;
39using int16 = signed short;
41using uint16 = unsigned short;
43using int32 = signed int;
45using uint32 = unsigned int;
46
47#if JUCE_MSVC
49 using int64 = __int64;
51 using uint64 = unsigned __int64;
52#else
54 using int64 = long long;
56 using uint64 = unsigned long long;
57#endif
58
59#ifndef DOXYGEN
65 #define literal64bit(longLiteral) (longLiteral##LL)
66#endif
67
68#if JUCE_64BIT
73#elif JUCE_MSVC
77 using pointer_sized_uint = _W64 unsigned int;
78#else
82 using pointer_sized_uint = unsigned int;
83#endif
84
85#if JUCE_WINDOWS && ! JUCE_MINGW
87#endif
88
89//==============================================================================
91template <typename... Types>
92void ignoreUnused (Types&&...) noexcept {}
93
102template <typename Type, size_t N>
103constexpr int numElementsInArray (Type (&)[N]) noexcept { return N; }
104
105//==============================================================================
106// Some useful maths functions that aren't always present with all compilers and build settings.
107
110template <typename Type>
111Type juce_hypot (Type a, Type b) noexcept
112{
113 #if JUCE_MSVC
114 return static_cast<Type> (_hypot (a, b));
115 #else
116 return static_cast<Type> (hypot (a, b));
117 #endif
118}
119
120#ifndef DOXYGEN
121template <>
122inline float juce_hypot (float a, float b) noexcept
123{
124 #if JUCE_MSVC
125 return _hypotf (a, b);
126 #else
127 return hypotf (a, b);
128 #endif
129}
130#endif
131
132//==============================================================================
137template <typename FloatType>
139{
141 static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L);
142
144 static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
145
147 static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
148
150 static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L);
151
153 static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
154};
155
156#ifndef DOXYGEN
158[[deprecated ("This is deprecated in favour of MathConstants<double>::pi.")]]
159const constexpr double double_Pi = MathConstants<double>::pi;
160
162[[deprecated ("This is deprecated in favour of MathConstants<float>::pi.")]]
163const constexpr float float_Pi = MathConstants<float>::pi;
164#endif
165
167template <typename FloatType>
168constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); }
169
171template <typename FloatType>
172constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); }
173
174//==============================================================================
178template <typename NumericType>
179bool juce_isfinite (NumericType value) noexcept
180{
184 {
185 return std::isfinite (value);
186 }
187 else
188 {
189 ignoreUnused (value);
190 return true;
191 }
192}
193
194//==============================================================================
200template <typename Type>
201constexpr bool exactlyEqual (Type a, Type b)
202{
203 JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfloat-equal")
204 return a == b;
205 JUCE_END_IGNORE_WARNINGS_GCC_LIKE
206}
207
214template <typename Type>
216{
217public:
218 Tolerance() = default;
219
228 {
229 return withMember (*this, &Tolerance::absolute, std::abs (newAbsolute));
230 }
231
240 {
241 return withMember (*this, &Tolerance::relative, std::abs (newRelative));
242 }
243
244 [[nodiscard]] Type getAbsolute() const { return absolute; }
245 [[nodiscard]] Type getRelative() const { return relative; }
246
247private:
248 Type absolute{};
249 Type relative{};
250};
251
256template <typename Type>
257static Tolerance<Type> absoluteTolerance (Type tolerance)
258{
259 return Tolerance<Type>{}.withAbsolute (tolerance);
260}
261
266template <typename Type>
267static Tolerance<Type> relativeTolerance (Type tolerance)
268{
269 return Tolerance<Type>{}.withRelative (tolerance);
270}
271
272
298template <typename Type, std::enable_if_t<std::is_floating_point_v<Type>, int> = 0>
299constexpr bool approximatelyEqual (Type a, Type b,
302 .withRelative (std::numeric_limits<Type>::epsilon()))
303{
304 if (! (juce_isfinite (a) && juce_isfinite (b)))
305 return exactlyEqual (a, b);
306
307 const auto diff = std::abs (a - b);
308
309 return diff <= tolerance.getAbsolute()
310 || diff <= tolerance.getRelative() * std::max (std::abs (a), std::abs (b));
311}
312
314template <typename Type, std::enable_if_t<! std::is_floating_point_v<Type>, int> = 0>
315constexpr bool approximatelyEqual (Type a, Type b)
316{
317 return a == b;
318}
319
320//==============================================================================
322template <typename FloatType>
323FloatType nextFloatUp (FloatType value) noexcept
324{
326}
327
329template <typename FloatType>
330FloatType nextFloatDown (FloatType value) noexcept
331{
333}
334
335//==============================================================================
336// Some indispensable min/max functions
337
339template <typename Type>
340constexpr Type jmax (Type a, Type b) { return a < b ? b : a; }
341
343template <typename Type>
344constexpr Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); }
345
347template <typename Type>
348constexpr Type jmax (Type a, Type b, Type c, Type d) { return jmax (a, jmax (b, c, d)); }
349
351template <typename Type>
352constexpr Type jmin (Type a, Type b) { return b < a ? b : a; }
353
355template <typename Type>
356constexpr Type jmin (Type a, Type b, Type c) { return b < a ? (c < b ? c : b) : (c < a ? c : a); }
357
359template <typename Type>
360constexpr Type jmin (Type a, Type b, Type c, Type d) { return jmin (a, jmin (b, c, d)); }
361
365template <typename Type>
366constexpr Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax)
367{
369}
370
372template <typename Type>
373Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax)
374{
375 jassert (! approximatelyEqual (sourceRangeMax, sourceRangeMin)); // mapping from a range of zero will produce NaN!
377}
378
389template <typename Type>
391{
392 jassert (logRangeMin > 0);
393 jassert (logRangeMax > 0);
394
397
398 return std::pow ((Type) 10.0, value0To1 * (logMax - logMin) + logMin);
399}
400
411template <typename Type>
413{
414 jassert (logRangeMin > 0);
415 jassert (logRangeMax > 0);
416
419
420 return (std::log10 (valueInLogRange) - logMin) / (logMax - logMin);
421}
422
424template <typename Type, typename Size>
425Type findMinimum (const Type* data, Size numValues)
426{
427 if (numValues <= 0)
428 return Type (0);
429
430 auto result = *data++;
431
432 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
433 {
434 auto v = *data++;
435
436 if (v < result)
437 result = v;
438 }
439
440 return result;
441}
442
444template <typename Type, typename Size>
445Type findMaximum (const Type* values, Size numValues)
446{
447 if (numValues <= 0)
448 return Type (0);
449
450 auto result = *values++;
451
452 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
453 {
454 auto v = *values++;
455
456 if (result < v)
457 result = v;
458 }
459
460 return result;
461}
462
464template <typename Type>
465void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest)
466{
467 if (numValues <= 0)
468 {
469 lowest = Type (0);
470 highest = Type (0);
471 }
472 else
473 {
474 auto mn = *values++;
475 auto mx = mn;
476
477 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
478 {
479 auto v = *values++;
480
481 if (mx < v) mx = v;
482 if (v < mn) mn = v;
483 }
484
485 lowest = mn;
486 highest = mx;
487 }
488}
489
490//==============================================================================
507template <typename Type>
509 Type upperLimit,
510 Type valueToConstrain) noexcept
511{
512 jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
513
517}
518
524template <typename Type1, typename Type2>
526{
527 jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
529}
530
531template <typename Type>
532bool isPositiveAndBelow (int valueToTest, Type upperLimit) noexcept
533{
534 jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
535 return static_cast<unsigned int> (valueToTest) < static_cast<unsigned int> (upperLimit);
536}
537
543template <typename Type1, typename Type2>
545{
546 jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
548}
549
550template <typename Type>
551bool isPositiveAndNotGreaterThan (int valueToTest, Type upperLimit) noexcept
552{
553 jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
554 return static_cast<unsigned int> (valueToTest) <= static_cast<unsigned int> (upperLimit);
555}
556
560template <typename Type>
561bool isWithin (Type a, Type b, Type tolerance) noexcept
562{
563 return std::abs (a - b) <= tolerance;
564}
565
566//==============================================================================
567#if JUCE_MSVC
568 #pragma optimize ("t", off)
569 #ifndef __INTEL_COMPILER
570 #pragma float_control (precise, on, push)
571 #endif
572#endif
573
584template <typename FloatType>
585int roundToInt (const FloatType value) noexcept
586{
587 #ifdef __INTEL_COMPILER
588 #pragma float_control (precise, on, push)
589 #endif
590
591 union { int asInt[2]; double asDouble; } n;
592 n.asDouble = ((double) value) + 6755399441055744.0;
593
594 #if JUCE_BIG_ENDIAN
595 return n.asInt [1];
596 #else
597 return n.asInt [0];
598 #endif
599}
600
601inline int roundToInt (int value) noexcept
602{
603 return value;
604}
605
606#if JUCE_MSVC
607 #ifndef __INTEL_COMPILER
608 #pragma float_control (pop)
609 #endif
610 #pragma optimize ("", on) // resets optimisations to the project defaults
611#endif
612
618inline int roundToIntAccurate (double value) noexcept
619{
620 #ifdef __INTEL_COMPILER
621 #pragma float_control (pop)
622 #endif
623
624 return roundToInt (value + 1.5e-8);
625}
626
627//==============================================================================
634template <typename FloatType>
635unsigned int truncatePositiveToUnsignedInt (FloatType value) noexcept
636{
637 jassert (value >= static_cast<FloatType> (0));
638 jassert (static_cast<FloatType> (value)
639 <= static_cast<FloatType> (std::numeric_limits<unsigned int>::max()));
640
641 return static_cast<unsigned int> (value);
642}
643
644//==============================================================================
646template <typename IntegerType>
647constexpr bool isPowerOfTwo (IntegerType value)
648{
649 return (value & (value - 1)) == 0;
650}
651
653inline int nextPowerOfTwo (int n) noexcept
654{
655 --n;
656 n |= (n >> 1);
657 n |= (n >> 2);
658 n |= (n >> 4);
659 n |= (n >> 8);
660 n |= (n >> 16);
661 return n + 1;
662}
663
668int findHighestSetBit (uint32 n) noexcept;
669
671constexpr int countNumberOfBits (uint32 n) noexcept
672{
673 n -= ((n >> 1) & 0x55555555);
674 n = (((n >> 2) & 0x33333333) + (n & 0x33333333));
675 n = (((n >> 4) + n) & 0x0f0f0f0f);
676 n += (n >> 8);
677 n += (n >> 16);
678 return (int) (n & 0x3f);
679}
680
682constexpr int countNumberOfBits (uint64 n) noexcept
683{
684 return countNumberOfBits ((uint32) n) + countNumberOfBits ((uint32) (n >> 32));
685}
686
690template <typename IntegerType>
697
699template <typename NumericType>
700inline constexpr NumericType square (NumericType n) noexcept
701{
702 return n * n;
703}
704
705//==============================================================================
714
723
724
725//==============================================================================
726#if JUCE_INTEL || DOXYGEN
731 #define JUCE_UNDENORMALISE(x) { (x) += 0.1f; (x) -= 0.1f; }
732#else
733 #define JUCE_UNDENORMALISE(x)
734#endif
735
736//==============================================================================
739namespace TypeHelpers
740{
752 template <typename Type> struct ParameterType { using type = const Type&; };
753
754 #ifndef DOXYGEN
755 template <typename Type> struct ParameterType <Type&> { using type = Type&; };
756 template <typename Type> struct ParameterType <Type*> { using type = Type*; };
757 template <> struct ParameterType <char> { using type = char; };
758 template <> struct ParameterType <unsigned char> { using type = unsigned char; };
759 template <> struct ParameterType <short> { using type = short; };
760 template <> struct ParameterType <unsigned short> { using type = unsigned short; };
761 template <> struct ParameterType <int> { using type = int; };
762 template <> struct ParameterType <unsigned int> { using type = unsigned int; };
763 template <> struct ParameterType <long> { using type = long; };
764 template <> struct ParameterType <unsigned long> { using type = unsigned long; };
765 template <> struct ParameterType <int64> { using type = int64; };
766 template <> struct ParameterType <uint64> { using type = uint64; };
767 template <> struct ParameterType <bool> { using type = bool; };
768 template <> struct ParameterType <float> { using type = float; };
769 template <> struct ParameterType <double> { using type = double; };
770 #endif
771
777 template <typename Type>
779
785 template <int bytes> struct UnsignedTypeWithSize {};
786
787 #ifndef DOXYGEN
788 template <> struct UnsignedTypeWithSize<1> { using type = uint8; };
789 template <> struct UnsignedTypeWithSize<2> { using type = uint16; };
790 template <> struct UnsignedTypeWithSize<4> { using type = uint32; };
791 template <> struct UnsignedTypeWithSize<8> { using type = uint64; };
792 #endif
793}
794
795//==============================================================================
796#ifndef DOXYGEN
797 [[deprecated ("Use roundToInt instead.")]] inline int roundDoubleToInt (double value) noexcept { return roundToInt (value); }
798 [[deprecated ("Use roundToInt instead.")]] inline int roundFloatToInt (float value) noexcept { return roundToInt (value); }
799 [[deprecated ("Use std::abs() instead.")]] inline int64 abs64 (int64 n) noexcept { return std::abs (n); }
800#endif
801
805template <typename T>
810
811} // namespace juce
A class encapsulating both relative and absolute tolerances for use in floating-point comparisons.
Tolerance withRelative(Type newRelative)
Returns a copy of this Tolerance object with a new relative tolerance.
Tolerance withAbsolute(Type newAbsolute)
Returns a copy of this Tolerance object with a new absolute tolerance.
hypot
T isfinite(T... args)
#define jassert(expression)
Platform-independent assertion macro.
typedef char
T log10(T... args)
typedef double
T max(T... args)
JUCE Namespace.
bool isWithin(Type a, Type b, Type tolerance) noexcept
Computes the absolute difference between two values and returns true if it is less than or equal to a...
Type mapToLog10(Type value0To1, Type logRangeMin, Type logRangeMax)
Remaps a normalised value (between 0 and 1) to a logarithmic target range.
unsigned short uint16
A platform-independent 16-bit unsigned integer type.
uint32 readLittleEndianBitsInBuffer(const void *buffer, uint32 startBit, uint32 numBits) noexcept
Reads a number of bits from a buffer at a given bit index.
int pointer_sized_int
A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it.
constexpr Type jmap(Type value0To1, Type targetRangeMin, Type targetRangeMax)
Remaps a normalised value (between 0 and 1) to a target range.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
void findMinAndMax(const Type *values, int numValues, Type &lowest, Type &highest)
Scans an array of values, returning the minimum and maximum values that it contains.
int findHighestSetBit(uint32 n) noexcept
Returns the index of the highest set bit in a (non-zero) number.
constexpr bool exactlyEqual(Type a, Type b)
Equivalent to operator==, but suppresses float-equality warnings.
int roundToIntAccurate(double value) noexcept
Fast floating-point-to-integer conversion.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
signed short int16
A platform-independent 16-bit signed integer type.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
signed int int32
A platform-independent 32-bit signed integer type.
FloatType nextFloatDown(FloatType value) noexcept
Returns the next representable value by FloatType in the direction of the lowest representable value.
int nextPowerOfTwo(int n) noexcept
Returns the smallest power-of-two which is equal to or greater than the given integer.
constexpr auto toUnderlyingType(T t) -> std::enable_if_t< std::is_enum_v< T >, std::underlying_type_t< T > >
Converts an enum to its underlying integral type.
void writeLittleEndianBitsInBuffer(void *buffer, uint32 startBit, uint32 numBits, uint32 value) noexcept
Writes a number of bits into a memory buffer at a given bit index.
constexpr NumericType square(NumericType n) noexcept
Returns the square of its argument.
void ignoreUnused(Types &&...) noexcept
Handy function for avoiding unused variables warning.
Object withMember(Object copy, Member OtherObject::*member, Other &&value)
Copies an object, sets one of the copy's members to the specified value, and then returns the copy.
constexpr int countNumberOfBits(uint32 n) noexcept
Returns the number of bits in a 32-bit integer.
signed char int8
A platform-independent 8-bit signed integer type.
Type findMaximum(const Type *values, Size numValues)
Scans an array of values, returning the maximum value that it contains.
Type juce_hypot(Type a, Type b) noexcept
Using juce_hypot is easier than dealing with the different types of hypot function that are provided ...
constexpr FloatType radiansToDegrees(FloatType radians) noexcept
Converts an angle in radians to degrees.
unsigned int pointer_sized_uint
An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it...
bool juce_isfinite(NumericType value) noexcept
The isfinite() method seems to vary between platforms, so this is a platform-independent function for...
unsigned long long uint64
A platform-independent 64-bit unsigned integer type.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
FloatType nextFloatUp(FloatType value) noexcept
Returns the next representable value by FloatType in the direction of the largest representable value...
bool isPositiveAndNotGreaterThan(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also less than or equal to a specified upper limit.
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
constexpr bool isPowerOfTwo(IntegerType value)
Returns true if the specified integer is a power-of-two.
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
constexpr FloatType degreesToRadians(FloatType degrees) noexcept
Converts an angle in degrees to radians.
unsigned int truncatePositiveToUnsignedInt(FloatType value) noexcept
Truncates a positive floating-point number to an unsigned int.
IntegerType negativeAwareModulo(IntegerType dividend, const IntegerType divisor) noexcept
Performs a modulo operation, but can cope with the dividend being negative.
Type findMinimum(const Type *data, Size numValues)
Scans an array of values, returning the minimum value that it contains.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
constexpr int numElementsInArray(Type(&)[N]) noexcept
Handy function for getting the number of elements in a simple const C array.
long long int64
A platform-independent 64-bit integer type.
Type mapFromLog10(Type valueInLogRange, Type logRangeMin, Type logRangeMax)
Remaps a logarithmic value in a target range to a normalised value (between 0 and 1).
T nextafter(T... args)
T pow(T... args)
Commonly used mathematical constants.
static constexpr FloatType halfPi
A predefined value for Pi / 2.
static constexpr FloatType twoPi
A predefined value for 2 * Pi.
static constexpr FloatType sqrt2
A predefined value for sqrt (2)
static constexpr FloatType pi
A predefined value for Pi.
static constexpr FloatType euler
A predefined value for Euler's number.
typedef long