@@ -857,6 +857,188 @@ namespace local
857
857
return result_is_ok;
858
858
}
859
859
860
+ template <typename FloatType>
861
+ auto test_pow_n_edge () -> bool
862
+ {
863
+ using float_type = FloatType;
864
+
865
+ std::mt19937_64 gen { time_point<typename std::mt19937_64::result_type>() };
866
+
867
+ std::uniform_real_distribution<float >
868
+ dist
869
+ (
870
+ static_cast <float >(1 .01L ),
871
+ static_cast <float >(1 .04L )
872
+ );
873
+
874
+ std::uniform_int_distribution<int >
875
+ dist_n
876
+ (
877
+ static_cast <int >(INT8_C (2 )),
878
+ static_cast <int >(INT8_C (12 ))
879
+ );
880
+
881
+ using std::fpclassify;
882
+ using std::isinf;
883
+ using std::pow;
884
+ using std::signbit;
885
+
886
+ auto result_is_ok = true ;
887
+
888
+ for (auto index = 0U ; index < 8U ; ++index)
889
+ {
890
+ static_cast <void >(index);
891
+
892
+ const float_type flt_x { static_cast <float_type>(dist (gen)) };
893
+
894
+ const auto flt_nrm = pow (flt_x, 0 );
895
+
896
+ const auto result_val_pow_zero_is_ok = (flt_nrm == static_cast <float_type>(1 .0L ));
897
+
898
+ BOOST_TEST (result_val_pow_zero_is_ok);
899
+
900
+ result_is_ok = (result_val_pow_zero_is_ok && result_is_ok);
901
+ }
902
+
903
+ for (auto index = 0U ; index < 8U ; ++index)
904
+ {
905
+ static_cast <void >(index);
906
+
907
+ const float_type arg_nan = ::my_nan<float_type>() * static_cast <float_type>(dist (gen));
908
+
909
+ const auto val_pow_nan = pow (arg_nan, dist_n (gen));
910
+
911
+ const auto result_val_pow_nan_is_ok = (isnan (val_pow_nan) && isnan (arg_nan));
912
+
913
+ BOOST_TEST (result_val_pow_nan_is_ok);
914
+
915
+ result_is_ok = (result_val_pow_nan_is_ok && result_is_ok);
916
+ }
917
+
918
+ for (auto index = 0U ; index < 8U ; ++index)
919
+ {
920
+ static_cast <void >(index);
921
+
922
+ const float_type arg_x_nrm = static_cast <float_type>(dist (gen));
923
+ const float_type arg_p_zero = static_cast <float_type>(dist_n (gen)) * (::my_zero<float_type>() * static_cast <float_type>(dist (gen)));
924
+ const int n_p_zero = static_cast <int >(arg_p_zero);
925
+
926
+ const auto val_pow_zero = pow (arg_x_nrm, n_p_zero);
927
+
928
+ const auto result_val_pow_zero_is_ok = ((val_pow_zero == float_type { 1 }) && (n_p_zero == 0 ));
929
+
930
+ BOOST_TEST (result_val_pow_zero_is_ok);
931
+
932
+ result_is_ok = (result_val_pow_zero_is_ok && result_is_ok);
933
+ }
934
+
935
+ for (auto index = static_cast <int >(UINT8_C (2 )); index <= static_cast <int >(UINT8_C (10 )); index += static_cast <int >(UINT8_C (2 )))
936
+ {
937
+ const auto flt_zero_pos = pow (static_cast <float_type>(0 .0L ), static_cast <float_type>(index));
938
+
939
+ const auto result_val_zero_pos_is_ok = (fpclassify (flt_zero_pos) == FP_ZERO);
940
+
941
+ BOOST_TEST (result_val_zero_pos_is_ok);
942
+
943
+ result_is_ok = (result_val_zero_pos_is_ok && result_is_ok);
944
+ }
945
+
946
+ for (auto index = static_cast <int >(UINT8_C (3 )); index <= static_cast <int >(UINT8_C (11 )); index += static_cast <int >(UINT8_C (2 )))
947
+ {
948
+ const auto flt_zero_pos = pow (static_cast <float_type>(0 .0L ), static_cast <float_type>(index));
949
+
950
+ const auto result_val_zero_pos_is_ok = (fpclassify (flt_zero_pos) == FP_ZERO);
951
+
952
+ BOOST_TEST (result_val_zero_pos_is_ok);
953
+
954
+ result_is_ok = (result_val_zero_pos_is_ok && result_is_ok);
955
+ }
956
+
957
+ for (auto index = static_cast <int >(INT8_C (-11 )); index <= static_cast <int >(INT8_C (-3 )); index += static_cast <int >(INT8_C (2 )))
958
+ {
959
+ const auto flt_zero_pos = pow (static_cast <float_type>(0 .0L ), static_cast <float_type>(index));
960
+
961
+ const auto result_val_zero_pos_is_ok = isinf (flt_zero_pos);
962
+
963
+ BOOST_TEST (result_val_zero_pos_is_ok);
964
+
965
+ result_is_ok = (result_val_zero_pos_is_ok && result_is_ok);
966
+ }
967
+
968
+ for (auto index = static_cast <int >(INT8_C (-10 )); index <= static_cast <int >(INT8_C (-2 )); index += static_cast <int >(INT8_C (2 )))
969
+ {
970
+ const auto flt_zero_pos = pow (static_cast <float_type>(0 .0L ), static_cast <float_type>(index));
971
+
972
+ const auto result_val_zero_pos_is_ok = isinf (flt_zero_pos);
973
+
974
+ BOOST_TEST (result_val_zero_pos_is_ok);
975
+
976
+ result_is_ok = (result_val_zero_pos_is_ok && result_is_ok);
977
+ }
978
+
979
+ for (auto i = static_cast <unsigned >(UINT8_C (0 )); i < static_cast <unsigned >(UINT8_C (8 )); ++i)
980
+ {
981
+ static_cast <void >(i);
982
+
983
+ const auto flt_near_one = static_cast <float_type>(dist (gen));
984
+
985
+ const auto flt_inf_neg = pow (-std::numeric_limits<float_type >::infinity () * flt_near_one, -3 );
986
+
987
+ const auto result_val_inf_neg_is_ok = (fpclassify (flt_inf_neg) == FP_ZERO);
988
+
989
+ BOOST_TEST (result_val_inf_neg_is_ok);
990
+
991
+ result_is_ok = (result_val_inf_neg_is_ok && result_is_ok);
992
+ }
993
+
994
+ for (auto i = static_cast <unsigned >(UINT8_C (0 )); i < static_cast <unsigned >(UINT8_C (8 )); ++i)
995
+ {
996
+ static_cast <void >(i);
997
+
998
+ const auto flt_near_one = static_cast <float_type>(dist (gen));
999
+
1000
+ const auto flt_inf_neg = pow (-std::numeric_limits<float_type>::infinity () * flt_near_one, 3 );
1001
+
1002
+ const auto result_val_inf_neg_is_ok = (fpclassify (flt_inf_neg) == FP_INFINITE);
1003
+
1004
+ BOOST_TEST (result_val_inf_neg_is_ok);
1005
+
1006
+ result_is_ok = (result_val_inf_neg_is_ok && result_is_ok);
1007
+ }
1008
+
1009
+ for (auto i = static_cast <unsigned >(UINT8_C (0 )); i < static_cast <unsigned >(UINT8_C (8 )); ++i)
1010
+ {
1011
+ static_cast <void >(i);
1012
+
1013
+ const auto flt_near_one = static_cast <float_type>(dist (gen));
1014
+
1015
+ const auto flt_nan = pow (std::numeric_limits<float_type>::quiet_NaN () * static_cast <float_type>(flt_near_one), 0 );
1016
+
1017
+ const auto result_val_nan_is_ok = (flt_nan == float_type { 1 .0F });
1018
+
1019
+ BOOST_TEST (result_val_nan_is_ok);
1020
+
1021
+ result_is_ok = (result_val_nan_is_ok && result_is_ok);
1022
+ }
1023
+
1024
+ for (auto i = static_cast <unsigned >(UINT8_C (0 )); i < static_cast <unsigned >(UINT8_C (8 )); ++i)
1025
+ {
1026
+ static_cast <void >(i);
1027
+
1028
+ const auto flt_near_one = static_cast <float_type>(dist (gen));
1029
+
1030
+ const auto flt_nan = pow (std::numeric_limits<float_type>::quiet_NaN () * static_cast <float_type>(flt_near_one), i + 1 );
1031
+
1032
+ const auto result_val_nan_is_ok = isnan (flt_nan);
1033
+
1034
+ BOOST_TEST (result_val_nan_is_ok);
1035
+
1036
+ result_is_ok = (result_val_nan_is_ok && result_is_ok);
1037
+ }
1038
+
1039
+ return result_is_ok;
1040
+ }
1041
+
860
1042
} // namespace local
861
1043
862
1044
auto main () -> int
@@ -870,6 +1052,7 @@ auto main() -> int
870
1052
local::test_sqrt_edge<float_type>();
871
1053
local::test_exp_edge<float_type>();
872
1054
local::test_log_edge<float_type>();
1055
+ local::test_pow_n_edge<float_type>();
873
1056
}
874
1057
875
1058
{
@@ -880,6 +1063,7 @@ auto main() -> int
880
1063
local::test_sqrt_edge<float_type>();
881
1064
local::test_exp_edge<float_type>();
882
1065
local::test_log_edge<float_type>();
1066
+ local::test_pow_n_edge<float_type>();
883
1067
}
884
1068
885
1069
{
@@ -890,6 +1074,7 @@ auto main() -> int
890
1074
local::test_sqrt_edge<float_type>();
891
1075
local::test_exp_edge<float_type>();
892
1076
local::test_log_edge<float_type>();
1077
+ local::test_pow_n_edge<float_type>();
893
1078
}
894
1079
#endif
895
1080
@@ -902,6 +1087,7 @@ auto main() -> int
902
1087
local::test_sqrt_edge<float_type>();
903
1088
local::test_exp_edge<float_type>();
904
1089
local::test_log_edge<float_type>();
1090
+ local::test_pow_n_edge<float_type>();
905
1091
}
906
1092
907
1093
return boost::report_errors ();
0 commit comments