35 #include <vnl/vnl_math.h>
42 #include <vxl_version.h>
106 #define itkTemplateFloatingToIntegerMacro(name) \
107 template <typename TReturn, typename TInput> \
108 inline TReturn name(TInput x) \
110 if constexpr (sizeof(TReturn) <= 4) \
112 return static_cast<TReturn>(Detail::name##_32(x)); \
114 else if constexpr (sizeof(TReturn) <= 8) \
116 return static_cast<TReturn>(Detail::name##_64(x)); \
120 return static_cast<TReturn>(Detail::name##_base<TReturn, TInput>(x)); \
177 template <
typename TReturn,
typename TInput>
181 return RoundHalfIntegerUp<TReturn, TInput>(x);
210 #undef itkTemplateFloatingToIntegerMacro
212 template <
typename TReturn,
typename TInput>
216 #ifdef ITK_USE_CONCEPT_CHECKING
219 #endif // ITK_USE_CONCEPT_CHECKING
221 auto ret = static_cast<TReturn>(x);
222 if constexpr (
sizeof(TReturn) >
sizeof(TInput) &&
229 else if constexpr (
sizeof(TReturn) >=
sizeof(TInput))
233 itk::RangeError _e(__FILE__, __LINE__);
237 else if (static_cast<TInput>(ret) != x ||
240 itk::RangeError _e(__FILE__, __LINE__);
253 template <
typename T>
269 template <
typename T>
275 return representOutput.
asFloat;
308 template <
typename T>
318 const T absDifference =
std::abs(x1 - x2);
319 if (absDifference <= maxAbsoluteDifference)
328 if (std::signbit(x1) != std::signbit(x2))
338 return ulps <= maxUlps;
352 template <
typename TFloatType1,
typename TFloatType2>
356 return FloatAlmostEqual<double>(x1, x2);
359 template <
typename TFloatType1,
typename TFloatType2>
363 return FloatAlmostEqual<double>(x1, x2);
366 template <
typename TFloatType1,
typename TFloatType2>
370 return FloatAlmostEqual<float>(x1, x2);
373 template <
typename TFloatType1,
typename TFloatType2>
377 return FloatAlmostEqual<float>(x1, x2);
380 template <
typename TFloatType1,
typename TFloatType2>
384 return FloatAlmostEqual<float>(x1, x2);
390 template <
typename TFloatType,
typename TIntType>
394 return FloatAlmostEqual<TFloatType>(floatingVariable, integerVariable);
400 template <
typename TIntType,
typename TFloatType>
410 template <
typename TSignedInt,
typename TUn
signedInt>
414 if (signedVariable < 0)
422 return signedVariable == static_cast<TSignedInt>(unsignedVariable);
428 template <
typename TUn
signedInt,
typename TSignedInt>
438 template <
typename TIntegerType1,
typename TIntegerType2>
449 template <
bool TInput1IsIntger,
bool TInput1IsSigned,
bool TInput2IsInteger,
bool TInput2IsSigned>
464 struct AlmostEqualsFunctionSelector<false, true, true, true>
471 struct AlmostEqualsFunctionSelector<false, true, true, false>
478 struct AlmostEqualsFunctionSelector<true, false, false, true>
485 struct AlmostEqualsFunctionSelector<true, true, false, true>
492 struct AlmostEqualsFunctionSelector<true, true, true, false>
499 struct AlmostEqualsFunctionSelector<true, false, true, true>
506 struct AlmostEqualsFunctionSelector<true, true, true, true>
513 struct AlmostEqualsFunctionSelector<true, false, true, false>
521 template <
typename TInputType1,
typename TInputType2>
522 struct AlmostEqualsScalarImplementer
524 static constexpr
bool TInputType1IsInteger = std::is_integral_v<TInputType1>;
525 static constexpr
bool TInputType1IsSigned = std::is_signed_v<TInputType1>;
526 static constexpr
bool TInputType2IsInteger = std::is_integral_v<TInputType2>;
527 static constexpr
bool TInputType2IsSigned = std::is_signed_v<TInputType2>;
529 using SelectedVersion =
typename AlmostEqualsFunctionSelector<TInputType1IsInteger,
531 TInputType2IsInteger,
532 TInputType2IsSigned>::SelectedVersion;
538 template <
typename TScalarType1,
typename TScalarType2>
540 AlmostEqualsScalarComparer(TScalarType1 x1, TScalarType2 x2)
542 return AlmostEqualsScalarImplementer<TScalarType1, TScalarType2>::SelectedVersion::
543 template AlmostEqualsFunction<TScalarType1, TScalarType2>(x1, x2);
550 struct AlmostEqualsScalarVsScalar
552 template <
typename TScalarType1,
typename TScalarType2>
554 AlmostEqualsFunction(TScalarType1 x1, TScalarType2 x2)
556 return AlmostEqualsScalarComparer(x1, x2);
562 struct AlmostEqualsComplexVsComplex
564 template <
typename TComplexType1,
typename TComplexType2>
566 AlmostEqualsFunction(TComplexType1 x1, TComplexType2 x2)
568 return AlmostEqualsScalarComparer(x1.real(), x2.real()) && AlmostEqualsScalarComparer(x1.imag(), x2.imag());
575 struct AlmostEqualsScalarVsComplex
577 template <
typename TScalarType,
typename TComplexType>
579 AlmostEqualsFunction(TScalarType scalarVariable, TComplexType complexVariable)
585 return AlmostEqualsScalarComparer(scalarVariable, complexVariable.real());
589 struct AlmostEqualsComplexVsScalar
591 template <
typename TComplexType,
typename TScalarType>
593 AlmostEqualsFunction(TComplexType complexVariable, TScalarType scalarVariable)
595 return AlmostEqualsScalarVsComplex::AlmostEqualsFunction(scalarVariable, complexVariable);
602 template <
bool T1IsComplex,
bool T2IsComplex>
603 struct AlmostEqualsComplexChooser
605 using ChosenVersion = AlmostEqualsScalarVsScalar;
609 struct AlmostEqualsComplexChooser<true, true>
611 using ChosenVersion = AlmostEqualsComplexVsComplex;
615 struct AlmostEqualsComplexChooser<false, true>
617 using ChosenVersion = AlmostEqualsScalarVsComplex;
621 struct AlmostEqualsComplexChooser<true, false>
623 using ChosenVersion = AlmostEqualsComplexVsScalar;
631 template <
typename T1,
typename T2>
632 struct AlmostEqualsComplexImplementer
637 using ChosenVersion =
typename AlmostEqualsComplexChooser<T1IsComplex, T2IsComplex>::ChosenVersion;
686 template <
typename T1,
typename T2>
690 return Detail::AlmostEqualsComplexImplementer<T1, T2>::ChosenVersion::AlmostEqualsFunction(x1, x2);
694 template <
typename T1,
typename T2>
724 template <
typename TInput1,
typename TInput2>
729 ITK_GCC_SUPPRESS_Wfloat_equal
735 template <
typename TInput1,
typename TInput2>
747 ITKCommon_EXPORT
bool
749 ITKCommon_EXPORT
bool
751 ITKCommon_EXPORT
bool
753 ITKCommon_EXPORT
bool
759 ITKCommon_EXPORT
unsigned short
761 ITKCommon_EXPORT
unsigned int
763 ITKCommon_EXPORT
unsigned long
765 ITKCommon_EXPORT
unsigned long long
773 template <
typename TReturnType = u
intmax_t>
774 constexpr TReturnType
777 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedProduct only supports unsigned return types");
781 return (a == 0) || (b == 0) ||
782 (((static_cast<TReturnType>(a * b) / a) == b) && ((static_cast<TReturnType>(a * b) / b) == a))
783 ? static_cast<TReturnType>(a * b)
784 : (assert(!
"UnsignedProduct overflow!"), 0);
795 template <
typename TReturnType = u
intmax_t>
796 constexpr TReturnType
799 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedPower only supports unsigned return types");
803 return (exponent == 0)
804 ? (assert(base > 0), 1)
805 : (exponent == 1) ? base
806 : UnsignedProduct<TReturnType>(UnsignedPower<TReturnType>(base, exponent / 2),
807 UnsignedPower<TReturnType>(base, (exponent + 1) / 2));
821 using vnl_math::angle_0_to_2pi;
822 using vnl_math::angle_minuspi_to_pi;
823 using vnl_math::rnd_halfinttoeven;
824 using vnl_math::rnd_halfintup;
826 using vnl_math::floor;
827 using vnl_math::ceil;
829 using vnl_math::sgn0;
830 using vnl_math::remainder_truncated;
831 using vnl_math::remainder_floored;
833 using vnl_math::cube;
834 using vnl_math::squared_magnitude;
856 return x < 0 ? static_cast<unsigned char>(-x) : x;
861 return static_cast<unsigned char>(x);
863 inline unsigned short
866 return x < 0 ? static_cast<unsigned short>(-x) : x;
868 inline unsigned short
884 inline unsigned long long
895 #endif // end of itkMath.h