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))
334 return ulps <= maxUlps;
348 template <
typename TFloatType1,
typename TFloatType2>
352 return FloatAlmostEqual<double>(x1, x2);
355 template <
typename TFloatType1,
typename TFloatType2>
359 return FloatAlmostEqual<double>(x1, x2);
362 template <
typename TFloatType1,
typename TFloatType2>
366 return FloatAlmostEqual<float>(x1, x2);
369 template <
typename TFloatType1,
typename TFloatType2>
373 return FloatAlmostEqual<float>(x1, x2);
376 template <
typename TFloatType1,
typename TFloatType2>
380 return FloatAlmostEqual<float>(x1, x2);
386 template <
typename TFloatType,
typename TIntType>
390 return FloatAlmostEqual<TFloatType>(floatingVariable, integerVariable);
396 template <
typename TIntType,
typename TFloatType>
406 template <
typename TSignedInt,
typename TUn
signedInt>
410 if (signedVariable < 0)
418 return signedVariable == static_cast<TSignedInt>(unsignedVariable);
424 template <
typename TUn
signedInt,
typename TSignedInt>
434 template <
typename TIntegerType1,
typename TIntegerType2>
445 template <
bool TInput1IsIntger,
bool TInput1IsSigned,
bool TInput2IsInteger,
bool TInput2IsSigned>
460 struct AlmostEqualsFunctionSelector<false, true, true, true>
467 struct AlmostEqualsFunctionSelector<false, true, true, false>
474 struct AlmostEqualsFunctionSelector<true, false, false, true>
481 struct AlmostEqualsFunctionSelector<true, true, false, true>
488 struct AlmostEqualsFunctionSelector<true, true, true, false>
495 struct AlmostEqualsFunctionSelector<true, false, true, true>
502 struct AlmostEqualsFunctionSelector<true, true, true, true>
509 struct AlmostEqualsFunctionSelector<true, false, true, false>
517 template <
typename TInputType1,
typename TInputType2>
518 struct AlmostEqualsScalarImplementer
520 static constexpr
bool TInputType1IsInteger = std::is_integral_v<TInputType1>;
521 static constexpr
bool TInputType1IsSigned = std::is_signed_v<TInputType1>;
522 static constexpr
bool TInputType2IsInteger = std::is_integral_v<TInputType2>;
523 static constexpr
bool TInputType2IsSigned = std::is_signed_v<TInputType2>;
525 using SelectedVersion =
typename AlmostEqualsFunctionSelector<TInputType1IsInteger,
527 TInputType2IsInteger,
528 TInputType2IsSigned>::SelectedVersion;
534 template <
typename TScalarType1,
typename TScalarType2>
536 AlmostEqualsScalarComparer(TScalarType1 x1, TScalarType2 x2)
538 return AlmostEqualsScalarImplementer<TScalarType1, TScalarType2>::SelectedVersion::
539 template AlmostEqualsFunction<TScalarType1, TScalarType2>(x1, x2);
546 struct AlmostEqualsScalarVsScalar
548 template <
typename TScalarType1,
typename TScalarType2>
550 AlmostEqualsFunction(TScalarType1 x1, TScalarType2 x2)
552 return AlmostEqualsScalarComparer(x1, x2);
558 struct AlmostEqualsComplexVsComplex
560 template <
typename TComplexType1,
typename TComplexType2>
562 AlmostEqualsFunction(TComplexType1 x1, TComplexType2 x2)
564 return AlmostEqualsScalarComparer(x1.real(), x2.real()) && AlmostEqualsScalarComparer(x1.imag(), x2.imag());
571 struct AlmostEqualsScalarVsComplex
573 template <
typename TScalarType,
typename TComplexType>
575 AlmostEqualsFunction(TScalarType scalarVariable, TComplexType complexVariable)
581 return AlmostEqualsScalarComparer(scalarVariable, complexVariable.real());
585 struct AlmostEqualsComplexVsScalar
587 template <
typename TComplexType,
typename TScalarType>
589 AlmostEqualsFunction(TComplexType complexVariable, TScalarType scalarVariable)
591 return AlmostEqualsScalarVsComplex::AlmostEqualsFunction(scalarVariable, complexVariable);
598 template <
bool T1IsComplex,
bool T2IsComplex>
599 struct AlmostEqualsComplexChooser
601 using ChosenVersion = AlmostEqualsScalarVsScalar;
605 struct AlmostEqualsComplexChooser<true, true>
607 using ChosenVersion = AlmostEqualsComplexVsComplex;
611 struct AlmostEqualsComplexChooser<false, true>
613 using ChosenVersion = AlmostEqualsScalarVsComplex;
617 struct AlmostEqualsComplexChooser<true, false>
619 using ChosenVersion = AlmostEqualsComplexVsScalar;
627 template <
typename T1,
typename T2>
628 struct AlmostEqualsComplexImplementer
633 using ChosenVersion =
typename AlmostEqualsComplexChooser<T1IsComplex, T2IsComplex>::ChosenVersion;
682 template <
typename T1,
typename T2>
686 return Detail::AlmostEqualsComplexImplementer<T1, T2>::ChosenVersion::AlmostEqualsFunction(x1, x2);
690 template <
typename T1,
typename T2>
720 template <
typename TInput1,
typename TInput2>
725 ITK_GCC_SUPPRESS_Wfloat_equal
731 template <
typename TInput1,
typename TInput2>
743 ITKCommon_EXPORT
bool
745 ITKCommon_EXPORT
bool
747 ITKCommon_EXPORT
bool
749 ITKCommon_EXPORT
bool
755 ITKCommon_EXPORT
unsigned short
757 ITKCommon_EXPORT
unsigned int
759 ITKCommon_EXPORT
unsigned long
761 ITKCommon_EXPORT
unsigned long long
769 template <
typename TReturnType = u
intmax_t>
770 constexpr TReturnType
773 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedProduct only supports unsigned return types");
777 return (a == 0) || (b == 0) ||
778 (((static_cast<TReturnType>(a * b) / a) == b) && ((static_cast<TReturnType>(a * b) / b) == a))
779 ? static_cast<TReturnType>(a * b)
780 : (assert(!
"UnsignedProduct overflow!"), 0);
791 template <
typename TReturnType = u
intmax_t>
792 constexpr TReturnType
795 static_assert(std::is_unsigned_v<TReturnType>,
"UnsignedPower only supports unsigned return types");
799 return (exponent == 0)
800 ? (assert(base > 0), 1)
801 : (exponent == 1) ? base
802 : UnsignedProduct<TReturnType>(UnsignedPower<TReturnType>(base, exponent / 2),
803 UnsignedPower<TReturnType>(base, (exponent + 1) / 2));
817 using vnl_math::angle_0_to_2pi;
818 using vnl_math::angle_minuspi_to_pi;
819 using vnl_math::rnd_halfinttoeven;
820 using vnl_math::rnd_halfintup;
822 using vnl_math::floor;
823 using vnl_math::ceil;
825 using vnl_math::sgn0;
826 using vnl_math::remainder_truncated;
827 using vnl_math::remainder_floored;
829 using vnl_math::cube;
830 using vnl_math::squared_magnitude;
852 return x < 0 ? static_cast<unsigned char>(-x) : x;
857 return static_cast<unsigned char>(x);
859 inline unsigned short
862 return x < 0 ? static_cast<unsigned short>(-x) : x;
864 inline unsigned short
880 inline unsigned long long
891 #endif // end of itkMath.h