@@ -50,25 +50,31 @@ typedef number<cpp_bin_float<std::numeric_limits<good_type>::digits, digit_base_
5050void test_special_cases ()
5151{
5252#if !defined(BOOST_CI_ASAN_BUILD) && !defined(BOOST_CI_USAN_BUID)
53- test_type max_val = (std::numeric_limits<test_type>::max)();
54- test_type min_val = (std::numeric_limits<test_type>::min)();
55- test_type eps = std::numeric_limits<test_type>::epsilon ();
56- test_type inf_val = (std::numeric_limits<test_type>::infinity)();
57- test_type nan_val = (std::numeric_limits<test_type>::quiet_NaN)();
58- test_type half = 0.5 ;
59- test_type one_point_5 = 1.5 ;
53+ test_type max_val = (std::numeric_limits<test_type>::max)();
54+ test_type denorm_min_val = std::numeric_limits<test_type>::denorm_min ();
55+ test_type min_val = (std::numeric_limits<test_type>::min)();
56+ test_type eps = std::numeric_limits<test_type>::epsilon ();
57+ test_type inf_val = (std::numeric_limits<test_type>::infinity)();
58+ test_type nan_val = (std::numeric_limits<test_type>::quiet_NaN)();
59+ test_type half = 0.5 ;
60+ test_type one_point_5 = 1.5 ;
6061
6162 BOOST_CHECK ((boost::math::isnormal)(max_val));
6263 BOOST_CHECK ((boost::math::isnormal)(-max_val));
6364 BOOST_CHECK ((boost::math::isnormal)(min_val));
6465 BOOST_CHECK ((boost::math::isnormal)(-min_val));
66+ BOOST_CHECK ((boost::math::isnormal)(denorm_min_val));
67+ BOOST_CHECK ((boost::math::isnormal)(-denorm_min_val));
6568 BOOST_CHECK ((boost::math::isinf)(inf_val));
6669 BOOST_CHECK ((boost::math::isinf)(-inf_val));
6770 BOOST_CHECK ((boost::math::isnan)(nan_val));
6871 BOOST_CHECK ((boost::math::isnan)(-nan_val));
6972
70- if (std::numeric_limits<test_type>::has_denorm)
71- min_val = std::numeric_limits<test_type>::denorm_min ();
73+ if (!std::numeric_limits<test_type>::has_denorm) {
74+ BOOST_CHECK_EQUAL (denorm_min_val, min_val);
75+ } else {
76+ BOOST_CHECK_LE (denorm_min_val, min_val);
77+ }
7278
7379 // Adding epsilon will increment 1.0:
7480 BOOST_CHECK (test_type (1 ) + eps != test_type (1 ));
@@ -91,23 +97,39 @@ void test_special_cases()
9197 BOOST_CHECK_EQUAL (max_val / -half, -inf_val);
9298 BOOST_CHECK_EQUAL (max_val / min_val, inf_val);
9399 BOOST_CHECK_EQUAL (max_val / -min_val, -inf_val);
100+ BOOST_CHECK_EQUAL (max_val / denorm_min_val, inf_val);
101+ BOOST_CHECK_EQUAL (max_val / -denorm_min_val, -inf_val);
94102 // Underflow:
95103 BOOST_CHECK_EQUAL (min_val * 2 - one_point_5 * min_val, 0 );
96104 BOOST_CHECK_EQUAL (-min_val * 2 + one_point_5 * min_val, 0 );
97105 BOOST_CHECK_EQUAL (min_val / 2 , 0 );
98106 BOOST_CHECK_EQUAL (min_val / max_val, 0 );
99107 BOOST_CHECK_EQUAL (min_val * half, 0 );
100108 BOOST_CHECK_EQUAL (min_val - min_val, 0 );
101- BOOST_CHECK_EQUAL (max_val - max_val, 0 );
102109 BOOST_CHECK_EQUAL (-min_val + min_val, 0 );
103- BOOST_CHECK_EQUAL (-max_val + max_val, 0 );
110+
111+ BOOST_CHECK_EQUAL (denorm_min_val * 2 - one_point_5 * denorm_min_val, 0 );
112+ BOOST_CHECK_EQUAL (-denorm_min_val * 2 + one_point_5 * denorm_min_val, 0 );
113+ BOOST_CHECK_EQUAL (denorm_min_val / 2 , 0 );
114+ BOOST_CHECK_EQUAL (denorm_min_val / max_val, 0 );
115+ BOOST_CHECK_EQUAL (denorm_min_val * half, 0 );
116+ BOOST_CHECK_EQUAL (denorm_min_val - denorm_min_val, 0 );
117+ BOOST_CHECK_EQUAL (-denorm_min_val + denorm_min_val, 0 );
104118 // Things which should not over/underflow:
105119 BOOST_CHECK_EQUAL ((min_val * 2 ) / 2 , min_val);
106- BOOST_CHECK_EQUAL ((max_val / 2 ) * 2 , max_val);
107120 BOOST_CHECK_GE ((min_val * 2.0000001 ) / 1.9999999999999999 , min_val);
108- BOOST_CHECK_LE ((max_val / 2.0000001 ) * 1.9999999999999999 , max_val);
109121 BOOST_CHECK_EQUAL (min_val * 2 - min_val, min_val);
122+
123+ BOOST_CHECK_EQUAL ((denorm_min_val * 2 ) / 2 , denorm_min_val);
124+ BOOST_CHECK_GE ((denorm_min_val * 2.0000001 ) / 1.9999999999999999 , denorm_min_val);
125+ BOOST_CHECK_EQUAL (denorm_min_val * 2 - denorm_min_val, denorm_min_val);
126+
127+ BOOST_CHECK_EQUAL (-max_val + max_val, 0 );
128+ BOOST_CHECK_EQUAL (max_val - max_val, 0 );
129+ BOOST_CHECK_EQUAL ((max_val / 2 ) * 2 , max_val);
130+ BOOST_CHECK_LE ((max_val / 2.0000001 ) * 1.9999999999999999 , max_val);
110131 BOOST_CHECK_EQUAL (max_val / 2 + max_val / 2 , max_val);
132+
111133 // Things involving zero:
112134 BOOST_CHECK_EQUAL (max_val + 0 , max_val);
113135 BOOST_CHECK_EQUAL (max_val - 0 , max_val);
@@ -210,12 +232,20 @@ void test_special_cases()
210232 // Corner cases:
211233 BOOST_CHECK_EQUAL ((max_val * half) / half, max_val);
212234 BOOST_CHECK_EQUAL ((max_val / 2 ) * 2 , max_val);
235+
213236 BOOST_CHECK_EQUAL ((min_val / half) * half, min_val);
214237 BOOST_CHECK_EQUAL ((min_val * 2 ) / 2 , min_val);
215238 BOOST_CHECK_EQUAL (max_val + min_val, max_val);
216239 BOOST_CHECK_EQUAL (min_val + max_val, max_val);
217240 BOOST_CHECK_EQUAL (max_val - min_val, max_val);
218241 BOOST_CHECK_EQUAL (min_val - max_val, -max_val);
242+
243+ BOOST_CHECK_EQUAL ((denorm_min_val / half) * half, denorm_min_val);
244+ BOOST_CHECK_EQUAL ((denorm_min_val * 2 ) / 2 , denorm_min_val);
245+ BOOST_CHECK_EQUAL (max_val + denorm_min_val, max_val);
246+ BOOST_CHECK_EQUAL (denorm_min_val + max_val, max_val);
247+ BOOST_CHECK_EQUAL (max_val - denorm_min_val, max_val);
248+ BOOST_CHECK_EQUAL (denorm_min_val - max_val, -max_val);
219249 // Signed zeros:
220250 BOOST_CHECK (boost::math::signbit (min_val * -min_val));
221251 BOOST_CHECK (boost::math::signbit (min_val * min_val) == 0 );
@@ -230,6 +260,24 @@ void test_special_cases()
230260 BOOST_CHECK (boost::math::signbit (-min_val / -2 ) == 0 );
231261 BOOST_CHECK (boost::math::signbit (-min_val / 2 ));
232262 test_type neg_zero = min_val * -min_val;
263+
264+ BOOST_CHECK (boost::math::signbit (denorm_min_val * -denorm_min_val));
265+ BOOST_CHECK (boost::math::signbit (denorm_min_val * denorm_min_val) == 0 );
266+ BOOST_CHECK (boost::math::signbit (-denorm_min_val * -denorm_min_val) == 0 );
267+ BOOST_CHECK (boost::math::signbit (-denorm_min_val * denorm_min_val));
268+ BOOST_CHECK (boost::math::signbit (denorm_min_val / max_val) == 0 );
269+ BOOST_CHECK (boost::math::signbit (denorm_min_val / -max_val));
270+ BOOST_CHECK (boost::math::signbit (-denorm_min_val / -max_val) == 0 );
271+ BOOST_CHECK (boost::math::signbit (-denorm_min_val / max_val));
272+ BOOST_CHECK (boost::math::signbit (denorm_min_val / 2 ) == 0 );
273+ BOOST_CHECK (boost::math::signbit (denorm_min_val / -2 ));
274+ BOOST_CHECK (boost::math::signbit (-denorm_min_val / -2 ) == 0 );
275+ BOOST_CHECK (boost::math::signbit (-denorm_min_val / 2 ));
276+
277+ test_type neg_denorm_zero = denorm_min_val * -denorm_min_val;
278+
279+ BOOST_CHECK_EQUAL (neg_zero, neg_denorm_zero);
280+
233281 test_type zero = 0 ;
234282 // Arithmetic involving signed zero:
235283 BOOST_CHECK_EQUAL (-neg_zero, 0 );
0 commit comments