@@ -1023,6 +1023,86 @@ bool test_lerp() {
1023
1023
return true ;
1024
1024
}
1025
1025
1026
+ void test_gh_1917 () {
1027
+ // GH-1917 <cmath>: lerp(1e+308, 5e+307, 4.0) spuriously overflows
1028
+ using bit_type = unsigned long long ;
1029
+ using float_bit_type = unsigned int ;
1030
+ STATIC_ASSERT (bit_cast<bit_type>(lerp (1e+308 , 5e+307 , 4.0 )) == bit_cast<bit_type>(-1e+308 ));
1031
+ {
1032
+ ExceptGuard except;
1033
+
1034
+ assert (bit_cast<bit_type>(lerp (1e+308 , 5e+307 , 4.0 )) == bit_cast<bit_type>(-1e+308 ));
1035
+ assert (check_feexcept (0 ));
1036
+ }
1037
+ STATIC_ASSERT (bit_cast<float_bit_type>(lerp (2e+38f , 1e+38f , 4 .0f )) == bit_cast<float_bit_type>(-2e+38f ));
1038
+ {
1039
+ ExceptGuard except;
1040
+
1041
+ assert (bit_cast<float_bit_type>(lerp (2e+38f , 1e+38f , 4 .0f )) == bit_cast<float_bit_type>(-2e+38f ));
1042
+ assert (check_feexcept (0 ));
1043
+ }
1044
+ #ifdef _M_FP_STRICT
1045
+ {
1046
+ ExceptGuard except;
1047
+ RoundGuard round{FE_UPWARD};
1048
+
1049
+ assert (bit_cast<bit_type>(lerp (1e+308 , 5e+307 , 4.0 )) == bit_cast<bit_type>(-1e+308 ));
1050
+ assert (check_feexcept (0 ));
1051
+ }
1052
+ {
1053
+ ExceptGuard except;
1054
+ RoundGuard round{FE_UPWARD};
1055
+
1056
+ assert (bit_cast<float_bit_type>(lerp (2e+38f , 1e+38f , 4 .0f )) == bit_cast<float_bit_type>(-2e+38f ));
1057
+ assert (check_feexcept (0 ));
1058
+ }
1059
+ {
1060
+ ExceptGuard except;
1061
+ RoundGuard round{FE_DOWNWARD};
1062
+
1063
+ assert (bit_cast<bit_type>(lerp (1e+308 , 5e+307 , 4.0 )) == bit_cast<bit_type>(-1e+308 ));
1064
+ assert (check_feexcept (0 ));
1065
+ }
1066
+ {
1067
+ ExceptGuard except;
1068
+ RoundGuard round{FE_DOWNWARD};
1069
+
1070
+ assert (bit_cast<float_bit_type>(lerp (2e+38f , 1e+38f , 4 .0f )) == bit_cast<float_bit_type>(-2e+38f ));
1071
+ assert (check_feexcept (0 ));
1072
+ }
1073
+ {
1074
+ ExceptGuard except;
1075
+ RoundGuard round{FE_TOWARDZERO};
1076
+
1077
+ assert (bit_cast<bit_type>(lerp (1e+308 , 5e+307 , 4.0 )) == bit_cast<bit_type>(-1e+308 ));
1078
+ assert (check_feexcept (0 ));
1079
+ }
1080
+ {
1081
+ ExceptGuard except;
1082
+ RoundGuard round{FE_TOWARDZERO};
1083
+
1084
+ assert (bit_cast<float_bit_type>(lerp (2e+38f , 1e+38f , 4 .0f )) == bit_cast<float_bit_type>(-2e+38f ));
1085
+ assert (check_feexcept (0 ));
1086
+ }
1087
+ {
1088
+ ExceptGuard except;
1089
+ const int r = feraiseexcept (FE_OVERFLOW);
1090
+
1091
+ assert (r == 0 );
1092
+ assert (bit_cast<bit_type>(lerp (1e+308 , 5e+307 , 4.0 )) == bit_cast<bit_type>(-1e+308 ));
1093
+ assert (check_feexcept (FE_OVERFLOW));
1094
+ }
1095
+ {
1096
+ ExceptGuard except;
1097
+ const int r = feraiseexcept (FE_OVERFLOW);
1098
+
1099
+ assert (r == 0 );
1100
+ assert (bit_cast<float_bit_type>(lerp (2e+38f , 1e+38f , 4 .0f )) == bit_cast<float_bit_type>(-2e+38f ));
1101
+ assert (check_feexcept (FE_OVERFLOW));
1102
+ }
1103
+ #endif // _M_FP_STRICT
1104
+ }
1105
+
1026
1106
constexpr bool test_gh_2112 () {
1027
1107
// GH-2112 <cmath>: std::lerp is missing Arithmetic overloads
1028
1108
assert (lerp (0 , 0 , 0 ) == 0.0 );
@@ -1108,6 +1188,7 @@ int main() {
1108
1188
test_lerp<double >();
1109
1189
test_lerp<long double >();
1110
1190
1191
+ test_gh_1917 ();
1111
1192
test_gh_2112 ();
1112
1193
STATIC_ASSERT (test_gh_2112 ());
1113
1194
}
0 commit comments