Browse Source

approximatelyEqual: Add customisable tolerances for floating-point comparisons

v7.0.9
Anthony Nicholls 2 years ago
parent
commit
2bb530f636
41 changed files with 813 additions and 124 deletions
  1. +2
    -0
      examples/DemoRunner/Builds/Android/app/CMakeLists.txt
  2. +3
    -0
      examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
  3. +3
    -0
      examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
  4. +3
    -0
      examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
  5. +3
    -0
      examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
  6. +3
    -0
      examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
  7. +3
    -0
      examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
  8. +2
    -0
      extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
  9. +3
    -0
      extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
  10. +3
    -0
      extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
  11. +2
    -0
      extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
  12. +3
    -0
      extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
  13. +3
    -0
      extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
  14. +3
    -0
      extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
  15. +3
    -0
      extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
  16. +3
    -0
      extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
  17. +3
    -0
      extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
  18. +3
    -0
      extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
  19. +3
    -0
      extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
  20. +2
    -0
      extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
  21. +3
    -0
      extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
  22. +3
    -0
      extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
  23. +3
    -0
      extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
  24. +3
    -0
      extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
  25. +3
    -0
      extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
  26. +3
    -0
      extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
  27. +3
    -0
      extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
  28. +3
    -0
      extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
  29. +3
    -0
      extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
  30. +3
    -0
      extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
  31. +3
    -0
      extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
  32. +3
    -0
      extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
  33. +3
    -0
      extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
  34. +3
    -0
      extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
  35. +3
    -0
      extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
  36. +3
    -0
      extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
  37. +1
    -1
      modules/juce_core/juce_core.cpp
  38. +223
    -121
      modules/juce_core/maths/juce_MathsFunctions.h
  39. +483
    -0
      modules/juce_core/maths/juce_MathsFunctions_test.cpp
  40. +1
    -1
      modules/juce_graphics/colour/juce_Colour.cpp
  41. +1
    -1
      modules/juce_graphics/geometry/juce_Point.h

+ 2
- 0
examples/DemoRunner/Builds/Android/app/CMakeLists.txt View File

@@ -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"


+ 3
- 0
examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj View File

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


+ 3
- 0
examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters View File

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


+ 3
- 0
examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj View File

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


+ 3
- 0
examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters View File

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


+ 3
- 0
examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj View File

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


+ 3
- 0
examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters View File

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


+ 2
- 0
extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt View File

@@ -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"


+ 3
- 0
extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj View File

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


+ 3
- 0
extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters View File

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


+ 2
- 0
extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt View File

@@ -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"


+ 3
- 0
extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj View File

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


+ 3
- 0
extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters View File

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


+ 3
- 0
extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj View File

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


+ 3
- 0
extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters View File

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


+ 3
- 0
extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj View File

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


+ 3
- 0
extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters View File

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


+ 3
- 0
extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj View File

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


+ 3
- 0
extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters View File

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


+ 2
- 0
extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt View File

@@ -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"


+ 3
- 0
extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj View File

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


+ 3
- 0
extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters View File

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


+ 3
- 0
extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj View File

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


+ 3
- 0
extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters View File

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


+ 3
- 0
extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj View File

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


+ 3
- 0
extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters View File

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


+ 3
- 0
extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj View File

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


+ 3
- 0
extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters View File

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


+ 3
- 0
extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj View File

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


+ 3
- 0
extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters View File

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


+ 3
- 0
extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj View File

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


+ 3
- 0
extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters View File

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


+ 3
- 0
extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj View File

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


+ 3
- 0
extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters View File

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


+ 3
- 0
extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj View File

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


+ 3
- 0
extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters View File

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


+ 1
- 1
modules/juce_core/juce_core.cpp View File

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


+ 223
- 121
modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -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
- 0
modules/juce_core/maths/juce_MathsFunctions_test.cpp View 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

+ 1
- 1
modules/juce_graphics/colour/juce_Colour.cpp View File

@@ -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);


+ 1
- 1
modules/juce_graphics/geometry/juce_Point.h View File

@@ -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…
Cancel
Save