mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
approximatelyEqual: Add customisable tolerances for floating-point comparisons
This commit is contained in:
parent
e4c87b766b
commit
2bb530f636
41 changed files with 813 additions and 124 deletions
|
|
@ -1018,6 +1018,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
@ -3075,6 +3076,7 @@ set_source_files_properties(
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
|
|||
|
|
@ -1316,6 +1316,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1930,6 +1930,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1316,6 +1316,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1930,6 +1930,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1316,6 +1316,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1930,6 +1930,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -894,6 +894,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
@ -2649,6 +2650,7 @@ set_source_files_properties(
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1639,6 +1639,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -927,6 +927,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
@ -2837,6 +2838,7 @@ set_source_files_properties(
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
|
|||
|
|
@ -1164,6 +1164,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1714,6 +1714,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1164,6 +1164,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1714,6 +1714,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1164,6 +1164,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1714,6 +1714,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -226,6 +226,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -163,6 +163,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -898,6 +898,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
@ -2733,6 +2734,7 @@ set_source_files_properties(
|
|||
"../../../../../modules/juce_core/maths/juce_Expression.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Expression.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions.h"
|
||||
"../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_NormalisableRange.h"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.cpp"
|
||||
"../../../../../modules/juce_core/maths/juce_Random.h"
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1669,6 +1669,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -362,6 +362,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -640,6 +640,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -362,6 +362,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -640,6 +640,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -362,6 +362,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -640,6 +640,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1172,6 +1172,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1738,6 +1738,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1172,6 +1172,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1738,6 +1738,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1172,6 +1172,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1738,6 +1738,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1155,6 +1155,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -1666,6 +1666,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp">
|
||||
<Filter>JUCE Modules\juce_core\maths</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -276,8 +276,8 @@
|
|||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
#include "containers/juce_HashMap_test.cpp"
|
||||
|
||||
#include "containers/juce_Optional_test.cpp"
|
||||
#include "maths/juce_MathsFunctions_test.cpp"
|
||||
#include "misc/juce_EnumHelpers_test.cpp"
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -86,16 +86,112 @@ using uint32 = unsigned int;
|
|||
using ssize_t = pointer_sized_int;
|
||||
#endif
|
||||
|
||||
/** Returns true if the two numbers are approximately equal. This is useful for floating-point
|
||||
and double comparisons.
|
||||
//==============================================================================
|
||||
/** Handy function for avoiding unused variables warning. */
|
||||
template <typename... Types>
|
||||
void ignoreUnused (Types&&...) noexcept {}
|
||||
|
||||
/** Handy function for getting the number of elements in a simple const C array.
|
||||
E.g.
|
||||
@code
|
||||
static int myArray[] = { 1, 2, 3 };
|
||||
|
||||
int numElements = numElementsInArray (myArray) // returns 3
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type, size_t N>
|
||||
constexpr int numElementsInArray (Type (&)[N]) noexcept { return N; }
|
||||
|
||||
//==============================================================================
|
||||
// Some useful maths functions that aren't always present with all compilers and build settings.
|
||||
|
||||
/** Using juce_hypot is easier than dealing with the different types of hypot function
|
||||
that are provided by the various platforms and compilers. */
|
||||
template <typename Type>
|
||||
bool approximatelyEqual (Type a, Type b) noexcept
|
||||
Type juce_hypot (Type a, Type b) noexcept
|
||||
{
|
||||
return std::abs (a - b) <= (std::numeric_limits<Type>::epsilon() * std::max (a, b))
|
||||
|| std::abs (a - b) < std::numeric_limits<Type>::min();
|
||||
#if JUCE_MSVC
|
||||
return static_cast<Type> (_hypot (a, b));
|
||||
#else
|
||||
return static_cast<Type> (hypot (a, b));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN
|
||||
template <>
|
||||
inline float juce_hypot (float a, float b) noexcept
|
||||
{
|
||||
#if JUCE_MSVC
|
||||
return _hypotf (a, b);
|
||||
#else
|
||||
return hypotf (a, b);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** Commonly used mathematical constants
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename FloatType>
|
||||
struct MathConstants
|
||||
{
|
||||
/** A predefined value for Pi */
|
||||
static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L);
|
||||
|
||||
/** A predefined value for 2 * Pi */
|
||||
static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
|
||||
|
||||
/** A predefined value for Pi / 2 */
|
||||
static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
|
||||
|
||||
/** A predefined value for Euler's number */
|
||||
static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L);
|
||||
|
||||
/** A predefined value for sqrt(2) */
|
||||
static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/** A double-precision constant for pi. */
|
||||
[[deprecated ("This is deprecated in favour of MathConstants<double>::pi.")]]
|
||||
const constexpr double double_Pi = MathConstants<double>::pi;
|
||||
|
||||
/** A single-precision constant for pi. */
|
||||
[[deprecated ("This is deprecated in favour of MathConstants<float>::pi.")]]
|
||||
const constexpr float float_Pi = MathConstants<float>::pi;
|
||||
#endif
|
||||
|
||||
/** Converts an angle in degrees to radians. */
|
||||
template <typename FloatType>
|
||||
constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); }
|
||||
|
||||
/** Converts an angle in radians to degrees. */
|
||||
template <typename FloatType>
|
||||
constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); }
|
||||
|
||||
//==============================================================================
|
||||
/** The isfinite() method seems to vary between platforms, so this is a
|
||||
platform-independent function for it.
|
||||
*/
|
||||
template <typename NumericType>
|
||||
bool juce_isfinite (NumericType value) noexcept
|
||||
{
|
||||
if constexpr (std::numeric_limits<NumericType>::has_infinity
|
||||
|| std::numeric_limits<NumericType>::has_quiet_NaN
|
||||
|| std::numeric_limits<NumericType>::has_signaling_NaN)
|
||||
{
|
||||
return std::isfinite (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ignoreUnused (value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Equivalent to operator==, but suppresses float-equality warnings.
|
||||
|
||||
This allows code to be explicit about float-equality checks that are known to have the correct
|
||||
|
|
@ -109,6 +205,128 @@ constexpr bool exactlyEqual (Type a, Type b)
|
|||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
}
|
||||
|
||||
/** A class encapsulating both relative and absolute tolerances for use in floating-point comparisons.
|
||||
|
||||
@see approximatelyEqual, absoluteTolerance, relativeTolerance
|
||||
*/
|
||||
template <typename Type>
|
||||
class Tolerance
|
||||
{
|
||||
public:
|
||||
Tolerance() = default;
|
||||
|
||||
/** Returns a copy of this Tolerance object with a new absolute tolerance.
|
||||
|
||||
If you just need a Tolerance object with an absolute tolerance, it might be worth using the
|
||||
absoluteTolerance() function.
|
||||
|
||||
@see getAbsolute, absoluteTolerance
|
||||
*/
|
||||
[[nodiscard]] Tolerance withAbsolute (Type newAbsolute)
|
||||
{
|
||||
return withMember (*this, &Tolerance::absolute, std::abs (newAbsolute));
|
||||
}
|
||||
|
||||
/** Returns a copy of this Tolerance object with a new relative tolerance.
|
||||
|
||||
If you just need a Tolerance object with a relative tolerance, it might be worth using the
|
||||
relativeTolerance() function.
|
||||
|
||||
@see getRelative, relativeTolerance
|
||||
*/
|
||||
[[nodiscard]] Tolerance withRelative (Type newRelative)
|
||||
{
|
||||
return withMember (*this, &Tolerance::relative, std::abs (newRelative));
|
||||
}
|
||||
|
||||
[[nodiscard]] Type getAbsolute() const { return absolute; }
|
||||
[[nodiscard]] Type getRelative() const { return relative; }
|
||||
|
||||
private:
|
||||
Type absolute{};
|
||||
Type relative{};
|
||||
};
|
||||
|
||||
/** Returns a type deduced Tolerance object containing only an absolute tolerance.
|
||||
|
||||
@see Tolerance::withAbsolute, approximatelyEqual
|
||||
*/
|
||||
template <typename Type>
|
||||
static Tolerance<Type> absoluteTolerance (Type tolerance)
|
||||
{
|
||||
return Tolerance<Type>{}.withAbsolute (tolerance);
|
||||
}
|
||||
|
||||
/** Returns a type deduced Tolerance object containing only a relative tolerance.
|
||||
|
||||
@see Tolerance::withRelative, approximatelyEqual
|
||||
*/
|
||||
template <typename Type>
|
||||
static Tolerance<Type> relativeTolerance (Type tolerance)
|
||||
{
|
||||
return Tolerance<Type>{}.withRelative (tolerance);
|
||||
}
|
||||
|
||||
|
||||
/** Returns true if the two numbers are approximately equal. This is useful for floating-point
|
||||
comparisons.
|
||||
|
||||
If a and b are not floating-point types, returns a == b.
|
||||
|
||||
If either a or b are not finite, returns exactlyEqual (a, b).
|
||||
|
||||
The default absolute tolerance is equal to the minimum normal value. This ensures
|
||||
differences that are subnormal are always considered equal. It is highly recommend this
|
||||
value is reviewed depending on the calculation being carried out. In general specifying an
|
||||
absolute value is useful when considering values close to zero. For example you might
|
||||
expect sin(pi) to return 0, but what it actually returns is close to the error of the value pi.
|
||||
Therefore, in this example it might be better to set the absolute tolerance to sin(pi).
|
||||
|
||||
The default relative tolerance is equal to the machine epsilon which is the difference between
|
||||
1.0 and the next floating-point value that can be represented by Type. In most cases this value
|
||||
is probably reasonable. This value is multiplied by the largest absolute value of a and b so as
|
||||
to scale relatively according to the input parameters. For example, specifying a relative value
|
||||
of 0.05 will ensure values return equal if the difference between them is less than or equal to
|
||||
5% of the larger of the two absolute values.
|
||||
|
||||
@param tolerance An object that represents both absolute and relative tolerances
|
||||
when evaluating if a and b are equal.
|
||||
|
||||
@see exactlyEqual
|
||||
*/
|
||||
template <typename Type>
|
||||
constexpr bool approximatelyEqual (Type a, Type b,
|
||||
Tolerance<Type> tolerance = Tolerance<Type>{}
|
||||
.withAbsolute (std::numeric_limits<Type>::min())
|
||||
.withRelative (std::numeric_limits<Type>::epsilon()))
|
||||
{
|
||||
if constexpr (! std::is_floating_point_v<Type>)
|
||||
return a == b;
|
||||
|
||||
if (! (juce_isfinite (a) && juce_isfinite (b)))
|
||||
return exactlyEqual (a, b);
|
||||
|
||||
const auto diff = std::abs (a - b);
|
||||
|
||||
return diff <= tolerance.getAbsolute()
|
||||
|| diff <= tolerance.getRelative() * std::max (std::abs (a), std::abs (b));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the next representable value by FloatType in the direction of the largest representable value. */
|
||||
template <typename FloatType>
|
||||
FloatType nextFloatUp (FloatType value) noexcept
|
||||
{
|
||||
return std::nextafter (value, std::numeric_limits<FloatType>::max());
|
||||
}
|
||||
|
||||
/** Returns the next representable value by FloatType in the direction of the lowest representable value. */
|
||||
template <typename FloatType>
|
||||
FloatType nextFloatDown (FloatType value) noexcept
|
||||
{
|
||||
return std::nextafter (value, std::numeric_limits<FloatType>::lowest());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Some indispensable min/max functions
|
||||
|
||||
|
|
@ -340,122 +558,6 @@ bool isWithin (Type a, Type b, Type tolerance) noexcept
|
|||
return std::abs (a - b) <= tolerance;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Handy function for avoiding unused variables warning. */
|
||||
template <typename... Types>
|
||||
void ignoreUnused (Types&&...) noexcept {}
|
||||
|
||||
/** Handy function for getting the number of elements in a simple const C array.
|
||||
E.g.
|
||||
@code
|
||||
static int myArray[] = { 1, 2, 3 };
|
||||
|
||||
int numElements = numElementsInArray (myArray) // returns 3
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type, size_t N>
|
||||
constexpr int numElementsInArray (Type (&)[N]) noexcept { return N; }
|
||||
|
||||
//==============================================================================
|
||||
// Some useful maths functions that aren't always present with all compilers and build settings.
|
||||
|
||||
/** Using juce_hypot is easier than dealing with the different types of hypot function
|
||||
that are provided by the various platforms and compilers. */
|
||||
template <typename Type>
|
||||
Type juce_hypot (Type a, Type b) noexcept
|
||||
{
|
||||
#if JUCE_MSVC
|
||||
return static_cast<Type> (_hypot (a, b));
|
||||
#else
|
||||
return static_cast<Type> (hypot (a, b));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN
|
||||
template <>
|
||||
inline float juce_hypot (float a, float b) noexcept
|
||||
{
|
||||
#if JUCE_MSVC
|
||||
return _hypotf (a, b);
|
||||
#else
|
||||
return hypotf (a, b);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** Commonly used mathematical constants
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <typename FloatType>
|
||||
struct MathConstants
|
||||
{
|
||||
/** A predefined value for Pi */
|
||||
static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L);
|
||||
|
||||
/** A predefined value for 2 * Pi */
|
||||
static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
|
||||
|
||||
/** A predefined value for Pi / 2 */
|
||||
static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
|
||||
|
||||
/** A predefined value for Euler's number */
|
||||
static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L);
|
||||
|
||||
/** A predefined value for sqrt(2) */
|
||||
static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/** A double-precision constant for pi. */
|
||||
[[deprecated ("This is deprecated in favour of MathConstants<double>::pi.")]]
|
||||
const constexpr double double_Pi = MathConstants<double>::pi;
|
||||
|
||||
/** A single-precision constant for pi. */
|
||||
[[deprecated ("This is deprecated in favour of MathConstants<float>::pi.")]]
|
||||
const constexpr float float_Pi = MathConstants<float>::pi;
|
||||
#endif
|
||||
|
||||
/** Converts an angle in degrees to radians. */
|
||||
template <typename FloatType>
|
||||
constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); }
|
||||
|
||||
/** Converts an angle in radians to degrees. */
|
||||
template <typename FloatType>
|
||||
constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** The isfinite() method seems to vary between platforms, so this is a
|
||||
platform-independent function for it.
|
||||
*/
|
||||
template <typename NumericType>
|
||||
bool juce_isfinite (NumericType) noexcept
|
||||
{
|
||||
return true; // Integer types are always finite
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool juce_isfinite (float value) noexcept
|
||||
{
|
||||
#if JUCE_WINDOWS && ! JUCE_MINGW
|
||||
return _finite (value) != 0;
|
||||
#else
|
||||
return std::isfinite (value);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool juce_isfinite (double value) noexcept
|
||||
{
|
||||
#if JUCE_WINDOWS && ! JUCE_MINGW
|
||||
return _finite (value) != 0;
|
||||
#else
|
||||
return std::isfinite (value);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_MSVC
|
||||
#pragma optimize ("t", off)
|
||||
|
|
|
|||
483
modules/juce_core/maths/juce_MathsFunctions_test.cpp
Normal file
483
modules/juce_core/maths/juce_MathsFunctions_test.cpp
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
template <typename T>
|
||||
String getTemplatedMathsFunctionUnitTestName (const String& functionName)
|
||||
{
|
||||
const auto getTypeName = []() -> String
|
||||
{
|
||||
if constexpr (std::is_same_v<float, T>)
|
||||
return "float";
|
||||
|
||||
if constexpr (std::is_same_v<double, T>)
|
||||
return "double";
|
||||
|
||||
if constexpr (std::is_same_v<long double, T>)
|
||||
return "long double";
|
||||
};
|
||||
|
||||
return functionName + "<" + getTypeName() + ">";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class ApproximatelyEqualTests final : public UnitTest
|
||||
{
|
||||
public:
|
||||
ApproximatelyEqualTests()
|
||||
: UnitTest { getTemplatedMathsFunctionUnitTestName<T> ("approximatelyEqual"), UnitTestCategories::maths }
|
||||
{}
|
||||
|
||||
void runTest() final
|
||||
{
|
||||
using limits = std::numeric_limits<T>;
|
||||
|
||||
constexpr auto zero = T{};
|
||||
constexpr auto one = T (1);
|
||||
constexpr auto min = limits::min();
|
||||
constexpr auto max = limits::max();
|
||||
constexpr auto epsilon = limits::epsilon();
|
||||
constexpr auto oneThird = one / (T) 3;
|
||||
|
||||
beginTest ("Equal values are always equal");
|
||||
{
|
||||
expect (approximatelyEqual (zero, zero));
|
||||
expect (approximatelyEqual (zero, -zero));
|
||||
expect (approximatelyEqual (-zero, -zero));
|
||||
|
||||
expect (approximatelyEqual (min, min));
|
||||
expect (approximatelyEqual (-min, -min));
|
||||
|
||||
expect (approximatelyEqual (one, one));
|
||||
expect (approximatelyEqual (-one, -one));
|
||||
|
||||
expect (approximatelyEqual (max, max));
|
||||
expect (approximatelyEqual (-max, -max));
|
||||
|
||||
const Tolerance<T> zeroTolerance{};
|
||||
|
||||
expect (approximatelyEqual (zero, zero, zeroTolerance));
|
||||
expect (approximatelyEqual (zero, -zero, zeroTolerance));
|
||||
expect (approximatelyEqual (-zero, -zero, zeroTolerance));
|
||||
|
||||
expect (approximatelyEqual (min, min, zeroTolerance));
|
||||
expect (approximatelyEqual (-min, -min, zeroTolerance));
|
||||
|
||||
expect (approximatelyEqual (one, one, zeroTolerance));
|
||||
expect (approximatelyEqual (-one, -one, zeroTolerance));
|
||||
|
||||
expect (approximatelyEqual (max, max, zeroTolerance));
|
||||
expect (approximatelyEqual (-max, -max, zeroTolerance));
|
||||
}
|
||||
|
||||
beginTest ("Comparing subnormal values to zero, returns true");
|
||||
{
|
||||
expect (! exactlyEqual (zero, nextFloatUp (zero)));
|
||||
expect (approximatelyEqual (zero, nextFloatUp (zero)));
|
||||
|
||||
expect (! exactlyEqual (zero, nextFloatDown (zero)));
|
||||
expect (approximatelyEqual (zero, nextFloatDown (zero)));
|
||||
|
||||
expect (! exactlyEqual (zero, nextFloatDown (min)));
|
||||
expect (approximatelyEqual (zero, nextFloatDown (min)));
|
||||
|
||||
expect (! exactlyEqual (zero, nextFloatUp (-min)));
|
||||
expect (approximatelyEqual (zero, nextFloatUp (-min)));
|
||||
}
|
||||
|
||||
beginTest ("Comparing the minimum normal value to zero, returns true");
|
||||
{
|
||||
expect (approximatelyEqual (zero, min));
|
||||
expect (approximatelyEqual (zero, -min));
|
||||
}
|
||||
|
||||
beginTest ("Comparing normal values greater than the minimum to zero, returns true");
|
||||
{
|
||||
expect (! approximatelyEqual (zero, one));
|
||||
expect (! approximatelyEqual (zero, epsilon));
|
||||
expect (! approximatelyEqual (zero, nextFloatUp (min)));
|
||||
expect (! approximatelyEqual (zero, nextFloatDown (-min)));
|
||||
}
|
||||
|
||||
beginTest ("Values with large ranges can be compared");
|
||||
{
|
||||
expect (! approximatelyEqual (zero, max));
|
||||
expect ( approximatelyEqual (zero, max, absoluteTolerance (max)));
|
||||
expect ( approximatelyEqual (zero, max, relativeTolerance (one)));
|
||||
expect (! approximatelyEqual (-one, max));
|
||||
expect (! approximatelyEqual (-max, max));
|
||||
}
|
||||
|
||||
beginTest ("Larger values have a boundary that is a factor of the epsilon");
|
||||
{
|
||||
for (auto exponent = 0; exponent < 127; ++exponent)
|
||||
{
|
||||
const auto value = std::pow ((T) 2, (T) exponent);
|
||||
const auto boundaryValue = value * (one + epsilon);
|
||||
|
||||
expect (juce_isfinite (value));
|
||||
expect (juce_isfinite (boundaryValue));
|
||||
|
||||
expect ( approximatelyEqual (value, boundaryValue));
|
||||
expect (! approximatelyEqual (value, nextFloatUp (boundaryValue)));
|
||||
|
||||
expect ( approximatelyEqual (-value, -boundaryValue));
|
||||
expect (! approximatelyEqual (-value, nextFloatDown (-boundaryValue)));
|
||||
}
|
||||
}
|
||||
|
||||
beginTest ("Tolerances scale with the values being compared");
|
||||
{
|
||||
|
||||
expect (approximatelyEqual ((T) 100'000'000'000'000.01,
|
||||
(T) 100'000'000'000'000.011));
|
||||
|
||||
expect (! approximatelyEqual ((T) 100.01,
|
||||
(T) 100.011));
|
||||
|
||||
expect (! approximatelyEqual ((T) 123'000, (T) 121'000, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 123'000, (T) 122'000, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 123'000, (T) 123'000, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 123'000, (T) 124'000, relativeTolerance ((T) 1e-2)));
|
||||
expect (! approximatelyEqual ((T) 123'000, (T) 125'000, relativeTolerance ((T) 1e-2)));
|
||||
|
||||
expect (! approximatelyEqual ((T) 123, (T) 121, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 123, (T) 122, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 123, (T) 123, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 123, (T) 124, relativeTolerance ((T) 1e-2)));
|
||||
expect (! approximatelyEqual ((T) 123, (T) 125, relativeTolerance ((T) 1e-2)));
|
||||
|
||||
expect (! approximatelyEqual ((T) 12.3, (T) 12.1, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 12.3, (T) 12.2, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 12.3, (T) 12.3, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 12.3, (T) 12.4, relativeTolerance ((T) 1e-2)));
|
||||
expect (! approximatelyEqual ((T) 12.3, (T) 12.5, relativeTolerance ((T) 1e-2)));
|
||||
|
||||
expect (! approximatelyEqual ((T) 1.23, (T) 1.21, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 1.23, (T) 1.22, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 1.23, (T) 1.23, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 1.23, (T) 1.24, relativeTolerance ((T) 1e-2)));
|
||||
expect (! approximatelyEqual ((T) 1.23, (T) 1.25, relativeTolerance ((T) 1e-2)));
|
||||
|
||||
expect (! approximatelyEqual ((T) 0.123, (T) 0.121, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 0.123, (T) 0.122, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 0.123, (T) 0.123, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 0.123, (T) 0.124, relativeTolerance ((T) 1e-2)));
|
||||
expect (! approximatelyEqual ((T) 0.123, (T) 0.125, relativeTolerance ((T) 1e-2)));
|
||||
|
||||
expect (! approximatelyEqual ((T) 0.000123, (T) 0.000121, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 0.000123, (T) 0.000122, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 0.000123, (T) 0.000123, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual ((T) 0.000123, (T) 0.000124, relativeTolerance ((T) 1e-2)));
|
||||
expect (! approximatelyEqual ((T) 0.000123, (T) 0.000125, relativeTolerance ((T) 1e-2)));
|
||||
}
|
||||
|
||||
beginTest ("The square of the square root of 2 is approximately 2");
|
||||
{
|
||||
constexpr auto two = (T) 2;
|
||||
const auto sqrtOfTwo = std::sqrt (two);
|
||||
|
||||
expect (approximatelyEqual (sqrtOfTwo * sqrtOfTwo, two));
|
||||
expect (approximatelyEqual (-sqrtOfTwo * sqrtOfTwo, -two));
|
||||
expect (approximatelyEqual (two / sqrtOfTwo, sqrtOfTwo));
|
||||
}
|
||||
|
||||
if constexpr (limits::has_quiet_NaN)
|
||||
{
|
||||
beginTest ("Values are never equal to NaN");
|
||||
{
|
||||
const auto nan = limits::quiet_NaN();
|
||||
|
||||
expect (! approximatelyEqual (nan, nan));
|
||||
|
||||
const auto expectNotEqualTo = [&](auto value)
|
||||
{
|
||||
expect (! approximatelyEqual (value, nan));
|
||||
expect (! approximatelyEqual (nan, value));
|
||||
};
|
||||
|
||||
expectNotEqualTo (zero);
|
||||
expectNotEqualTo (-zero);
|
||||
expectNotEqualTo (min);
|
||||
expectNotEqualTo (-min);
|
||||
expectNotEqualTo (one);
|
||||
expectNotEqualTo (-one);
|
||||
expectNotEqualTo (max);
|
||||
expectNotEqualTo (-max);
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (limits::has_infinity)
|
||||
{
|
||||
beginTest ("Only infinity is equal to infinity");
|
||||
{
|
||||
const auto inf = limits::infinity();
|
||||
expect (approximatelyEqual (inf, inf));
|
||||
expect (approximatelyEqual (-inf, -inf));
|
||||
expect (! approximatelyEqual (inf, -inf));
|
||||
expect (! approximatelyEqual (-inf, inf));
|
||||
|
||||
const auto expectNotEqualTo = [&](auto value)
|
||||
{
|
||||
expect (! approximatelyEqual (value, inf));
|
||||
expect (! approximatelyEqual (value, -inf));
|
||||
expect (! approximatelyEqual (inf, value));
|
||||
expect (! approximatelyEqual (-inf, value));
|
||||
};
|
||||
|
||||
expectNotEqualTo (zero);
|
||||
expectNotEqualTo (-zero);
|
||||
expectNotEqualTo (min);
|
||||
expectNotEqualTo (-min);
|
||||
expectNotEqualTo (one);
|
||||
expectNotEqualTo (-one);
|
||||
expectNotEqualTo (max);
|
||||
expectNotEqualTo (-max);
|
||||
}
|
||||
}
|
||||
|
||||
beginTest ("Can set an absolute tolerance");
|
||||
{
|
||||
constexpr std::array<T, 7> negativePowersOfTwo
|
||||
{
|
||||
(T) 0.5 /* 2^-1 */,
|
||||
(T) 0.25 /* 2^-2 */,
|
||||
(T) 0.125 /* 2^-3 */,
|
||||
(T) 0.0625 /* 2^-4 */,
|
||||
(T) 0.03125 /* 2^-5 */,
|
||||
(T) 0.015625 /* 2^-6 */,
|
||||
(T) 0.0078125 /* 2^-7 */
|
||||
};
|
||||
|
||||
const auto testTolerance = [&](auto tolerance)
|
||||
{
|
||||
const auto t = Tolerance<T>{}.withAbsolute ((T) tolerance);
|
||||
|
||||
const auto testValue= [&](auto value)
|
||||
{
|
||||
const auto boundary = value + tolerance;
|
||||
|
||||
expect (approximatelyEqual (value, boundary, t));
|
||||
expect (! approximatelyEqual (value, nextFloatUp (boundary), t));
|
||||
|
||||
expect (approximatelyEqual (-value, -boundary, t));
|
||||
expect (! approximatelyEqual (-value, nextFloatDown (-boundary), t));
|
||||
};
|
||||
|
||||
testValue (zero);
|
||||
testValue (min);
|
||||
testValue (epsilon);
|
||||
testValue (one);
|
||||
|
||||
for (const auto value : negativePowersOfTwo)
|
||||
testValue (value);
|
||||
};
|
||||
|
||||
for (const auto toleranceValue : negativePowersOfTwo)
|
||||
testTolerance (toleranceValue);
|
||||
}
|
||||
|
||||
beginTest ("Can set a relative tolerance");
|
||||
{
|
||||
expect (! approximatelyEqual (oneThird, (T) 0.34, relativeTolerance ((T) 1e-2)));
|
||||
expect ( approximatelyEqual (oneThird, (T) 0.334, relativeTolerance ((T) 1e-2)));
|
||||
|
||||
expect (! approximatelyEqual (oneThird, (T) 0.334, relativeTolerance ((T) 1e-3)));
|
||||
expect ( approximatelyEqual (oneThird, (T) 0.3334, relativeTolerance ((T) 1e-3)));
|
||||
|
||||
expect (! approximatelyEqual (oneThird, (T) 0.3334, relativeTolerance ((T) 1e-4)));
|
||||
expect ( approximatelyEqual (oneThird, (T) 0.33334, relativeTolerance ((T) 1e-4)));
|
||||
|
||||
expect (! approximatelyEqual (oneThird, (T) 0.33334, relativeTolerance ((T) 1e-5)));
|
||||
expect ( approximatelyEqual (oneThird, (T) 0.333334, relativeTolerance ((T) 1e-5)));
|
||||
|
||||
expect (! approximatelyEqual (oneThird, (T) 0.333334, relativeTolerance ((T) 1e-6)));
|
||||
expect ( approximatelyEqual (oneThird, (T) 0.3333334, relativeTolerance ((T) 1e-6)));
|
||||
|
||||
expect (! approximatelyEqual (oneThird, (T) 0.3333334, relativeTolerance ((T) 1e-7)));
|
||||
expect ( approximatelyEqual (oneThird, (T) 0.33333334, relativeTolerance ((T) 1e-7)));
|
||||
|
||||
expect ( approximatelyEqual ((T) 1e6, (T) 1e6 + (T) 1, relativeTolerance ((T) 1e-6)));
|
||||
expect (! approximatelyEqual ((T) 1e6, (T) 1e6 + (T) 1, relativeTolerance ((T) 1e-7)));
|
||||
|
||||
expect ( approximatelyEqual ((T) -1e-6, (T) -1.0000009e-6, relativeTolerance ((T) 1e-6)));
|
||||
expect (! approximatelyEqual ((T) -1e-6, (T) -1.0000009e-6, relativeTolerance ((T) 1e-7)));
|
||||
|
||||
const auto a = (T) 1.234567;
|
||||
const auto b = (T) 1.234568;
|
||||
|
||||
for (auto exponent = 0; exponent < 39; ++exponent)
|
||||
{
|
||||
const auto m = std::pow ((T) 10, (T) exponent);
|
||||
expect ( approximatelyEqual (a * m, b * m, relativeTolerance ((T) 1e-6)));
|
||||
expect (! approximatelyEqual (a * m, b * m, relativeTolerance ((T) 1e-7)));
|
||||
}
|
||||
}
|
||||
|
||||
beginTest ("A relative tolerance is always scaled by the maximum value");
|
||||
{
|
||||
expect ( approximatelyEqual ((T) 9, (T) 10, absoluteTolerance ((T) 10.0 * (T) 0.1)));
|
||||
expect (! approximatelyEqual ((T) 9, (T) 10, absoluteTolerance ((T) 9.0 * (T) 0.1)));
|
||||
|
||||
expect (approximatelyEqual ((T) 9, (T) 10, relativeTolerance ((T) 0.1)));
|
||||
expect (approximatelyEqual ((T) 10, (T) 9, relativeTolerance ((T) 0.1)));
|
||||
}
|
||||
|
||||
beginTest ("Documentation examples");
|
||||
{
|
||||
constexpr auto pi = MathConstants<T>::pi;
|
||||
|
||||
expect (! approximatelyEqual (zero, std::sin (pi)));
|
||||
expect ( approximatelyEqual (zero, std::sin (pi), absoluteTolerance (std::sin (pi))));
|
||||
|
||||
expect ( approximatelyEqual ((T) 100, (T) 95, relativeTolerance ((T) 0.05)));
|
||||
expect (! approximatelyEqual ((T) 100, (T) 94, relativeTolerance ((T) 0.05)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class IsFiniteTests final : public UnitTest
|
||||
{
|
||||
public:
|
||||
IsFiniteTests()
|
||||
: UnitTest { getTemplatedMathsFunctionUnitTestName<T> ("juce_isfinite"), UnitTestCategories::maths }
|
||||
{}
|
||||
|
||||
void runTest() final
|
||||
{
|
||||
using limits = std::numeric_limits<T>;
|
||||
|
||||
constexpr auto zero = T{};
|
||||
constexpr auto one = (T) 1;
|
||||
constexpr auto max = limits::max();
|
||||
constexpr auto inf = limits::infinity();
|
||||
constexpr auto nan = limits::quiet_NaN();
|
||||
|
||||
beginTest ("Zero is finite");
|
||||
{
|
||||
expect (juce_isfinite (zero));
|
||||
expect (juce_isfinite (-zero));
|
||||
}
|
||||
|
||||
beginTest ("Subnormals are finite");
|
||||
{
|
||||
expect (juce_isfinite (nextFloatUp (zero)));
|
||||
expect (juce_isfinite (nextFloatDown (zero)));
|
||||
}
|
||||
|
||||
beginTest ("One is finite");
|
||||
{
|
||||
expect (juce_isfinite (one));
|
||||
expect (juce_isfinite (-one));
|
||||
}
|
||||
|
||||
beginTest ("Max is finite");
|
||||
{
|
||||
expect (juce_isfinite (max));
|
||||
expect (juce_isfinite (-max));
|
||||
}
|
||||
|
||||
beginTest ("Infinity is not finite");
|
||||
{
|
||||
expect (! juce_isfinite (inf));
|
||||
expect (! juce_isfinite (-inf));
|
||||
}
|
||||
|
||||
beginTest ("NaN is not finite");
|
||||
{
|
||||
expect (! juce_isfinite (nan));
|
||||
expect (! juce_isfinite (-nan));
|
||||
expect (! juce_isfinite (std::sqrt ((T) -1)));
|
||||
expect (! juce_isfinite (inf * zero));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class NextFloatTests final : public UnitTest
|
||||
{
|
||||
public:
|
||||
NextFloatTests()
|
||||
: UnitTest { getTemplatedMathsFunctionUnitTestName<T> ("nextFloat"), UnitTestCategories::maths }
|
||||
{}
|
||||
|
||||
void runTest() final
|
||||
{
|
||||
using limits = std::numeric_limits<T>;
|
||||
|
||||
constexpr auto zero = T{};
|
||||
constexpr auto one = T (1);
|
||||
constexpr auto min = limits::min();
|
||||
constexpr auto epsilon = limits::epsilon();
|
||||
|
||||
beginTest ("nextFloat from zero is subnormal");
|
||||
{
|
||||
expect (juce_isfinite (nextFloatUp (zero)));
|
||||
expect (! exactlyEqual (zero, nextFloatUp (zero)));
|
||||
expect (! std::isnormal (nextFloatUp (zero)));
|
||||
|
||||
expect (juce_isfinite (nextFloatDown (zero)));
|
||||
expect (! exactlyEqual (zero, nextFloatDown (zero)));
|
||||
expect (! std::isnormal (nextFloatDown (zero)));
|
||||
}
|
||||
|
||||
beginTest ("nextFloat from min, towards zero, is subnormal");
|
||||
{
|
||||
expect (std::isnormal (min));
|
||||
expect (std::isnormal (-min));
|
||||
expect (! std::isnormal (nextFloatDown (min)));
|
||||
expect (! std::isnormal (nextFloatUp (-min)));
|
||||
}
|
||||
|
||||
beginTest ("nextFloat from one matches epsilon");
|
||||
{
|
||||
expect (! exactlyEqual (one, nextFloatUp (one)));
|
||||
expect ( exactlyEqual (one + epsilon, nextFloatUp (one)));
|
||||
|
||||
expect (! exactlyEqual (-one, nextFloatDown (-one)));
|
||||
expect ( exactlyEqual (-one - epsilon, nextFloatDown (-one)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct MathsFloatingPointFunctionsTests
|
||||
{
|
||||
IsFiniteTests<Type> isFiniteTests;
|
||||
NextFloatTests<Type> nextFloatTests;
|
||||
ApproximatelyEqualTests<Type> approximatelyEqualTests;
|
||||
};
|
||||
|
||||
struct MathsFunctionsTests
|
||||
{
|
||||
MathsFloatingPointFunctionsTests<float> floatFunctionTests;
|
||||
MathsFloatingPointFunctionsTests<double> doubleFunctionTests;
|
||||
MathsFloatingPointFunctionsTests<long double> longDoubleFunctionTests;
|
||||
};
|
||||
|
||||
static MathsFunctionsTests mathsFunctionsTests;
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -44,7 +44,7 @@ namespace ColourHelpers
|
|||
|
||||
float hue = 0.0f;
|
||||
|
||||
if (hi > 0 && ! approximatelyEqual (hi, lo))
|
||||
if (hi > 0 && ! exactlyEqual (hi, lo))
|
||||
{
|
||||
auto invDiff = 1.0f / (float) (hi - lo);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
constexpr bool isOrigin() const noexcept { return operator== (Point()); }
|
||||
|
||||
/** Returns true if the coordinates are finite values. */
|
||||
constexpr inline bool isFinite() const noexcept { return juce_isfinite(x) && juce_isfinite(y); }
|
||||
constexpr inline bool isFinite() const noexcept { return juce_isfinite (x) && juce_isfinite (y); }
|
||||
|
||||
/** Returns the point's x coordinate. */
|
||||
constexpr inline ValueType getX() const noexcept { return x; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue