@@ -90,5 +90,45 @@ int main()
9090 const uint128_t copied {from_macro};
9191 std::cout << " Copy constructed: " << copied << std::endl;
9292
93+ std::cout << " \n === Floating-Point Construction ===" << std::endl;
94+
95+ // Floating-point construction truncates toward zero, matching the behavior of
96+ // a static_cast from a floating-point type to a built-in integer.
97+ constexpr uint128_t from_double {12345.9 };
98+ std::cout << " uint128_t from 12345.9 (truncated): " << from_double << std::endl;
99+
100+ constexpr int128_t from_negative_double {-12345.9 };
101+ std::cout << " int128_t from -12345.9 (truncated toward zero): " << from_negative_double << std::endl;
102+
103+ // Values that exceed the 64-bit range are routed through the full 128-bit decomposition.
104+ const double two_to_the_100 {1.2676506002282294e30 }; // 2^100
105+ const uint128_t large_from_double {two_to_the_100};
106+ std::cout << " uint128_t from 2^100: " << large_from_double << std::endl;
107+
108+ std::cout << " \n === Floating-Point Edge Cases ===" << std::endl;
109+
110+ // NaN yields zero for both signed and unsigned (mirrors libgcc's __fix(uns)Xfti).
111+ const double nan_value {std::numeric_limits<double >::quiet_NaN ()};
112+ const uint128_t unsigned_from_nan {nan_value};
113+ const int128_t signed_from_nan {nan_value};
114+ std::cout << " uint128_t from NaN: " << unsigned_from_nan << std::endl;
115+ std::cout << " int128_t from NaN: " << signed_from_nan << std::endl;
116+
117+ // Negative values are clamped to zero when constructing uint128_t.
118+ const uint128_t unsigned_from_negative {-1.0 };
119+ std::cout << " uint128_t from -1.0 (clamped to zero): " << unsigned_from_negative << std::endl;
120+
121+ // Positive overflow saturates: anything >= 2^128 (including +infinity) becomes UINT128_MAX.
122+ const double infinity {std::numeric_limits<double >::infinity ()};
123+ const uint128_t saturated_unsigned {infinity};
124+ std::cout << " uint128_t from +infinity (saturates to UINT128_MAX): " << saturated_unsigned << std::endl;
125+
126+ // For int128_t, values >= 2^127 saturate to INT128_MAX and values <= -2^127 saturate to INT128_MIN.
127+ const double huge {1e40 }; // Well beyond 2^127 (~ 1.7e38)
128+ const int128_t saturated_positive {huge};
129+ const int128_t saturated_negative {-huge};
130+ std::cout << " int128_t from 1e40 (saturates to INT128_MAX): " << saturated_positive << std::endl;
131+ std::cout << " int128_t from -1e40 (saturates to INT128_MIN): " << saturated_negative << std::endl;
132+
93133 return 0 ;
94134}
0 commit comments