2222
2323#include < boost/core/lightweight_test.hpp>
2424
25+ template <typename DecimalType> auto my_zero () -> DecimalType&;
26+ template <typename DecimalType> auto my_one () -> DecimalType&;
27+ template <typename DecimalType> auto my_inf () -> DecimalType&;
28+
2529namespace local
2630{
2731 template <typename IntegralTimePointType,
@@ -182,6 +186,114 @@ namespace local
182186 return result_is_ok;
183187 }
184188
189+ template <typename DecimalType, typename FloatType>
190+ auto test_log10_edge () -> bool
191+ {
192+ using decimal_type = DecimalType;
193+ using float_type = FloatType;
194+
195+ std::mt19937_64 gen;
196+
197+ gen.seed (time_point<typename std::mt19937_64::result_type>());
198+
199+ std::uniform_real_distribution<float_type> dist (1 .0F , 2 .0F );
200+
201+ volatile auto result_is_ok = true ;
202+
203+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
204+ {
205+ static_cast <void >(index);
206+
207+ const auto log_zero = log10 (::my_zero<decimal_type>() * static_cast <decimal_type>(dist (gen)));
208+
209+ const volatile auto result_log_zero_is_ok = (isinf (log_zero) && (log_zero < ::my_zero<decimal_type>()));
210+
211+ BOOST_TEST (result_log_zero_is_ok);
212+
213+ result_is_ok = (result_log_zero_is_ok && result_is_ok);
214+ }
215+
216+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
217+ {
218+ static_cast <void >(index);
219+
220+ const auto log_zero_minus = log10 (-::my_zero<decimal_type>() * static_cast <decimal_type>(dist (gen)));
221+
222+ const volatile auto result_log_zero_minus_is_ok = (isinf (log_zero_minus) && (log_zero_minus < ::my_zero<decimal_type>()));
223+
224+ BOOST_TEST (result_log_zero_minus_is_ok);
225+
226+ result_is_ok = (result_log_zero_minus_is_ok && result_is_ok);
227+ }
228+
229+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
230+ {
231+ static_cast <void >(index);
232+
233+ const auto log_one = log10 (::my_one<decimal_type>());
234+
235+ const volatile auto result_log_one_is_ok = (log_one == ::my_zero<decimal_type>() * static_cast <decimal_type>(dist (gen)));
236+
237+ BOOST_TEST (result_log_one_is_ok);
238+
239+ result_is_ok = (result_log_one_is_ok && result_is_ok);
240+ }
241+
242+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
243+ {
244+ static_cast <void >(index);
245+
246+ const auto log_one_minus = log10 (-::my_one<decimal_type>());
247+
248+ const volatile auto result_log_one_minus_is_ok = isnan (log_one_minus);
249+
250+ BOOST_TEST (result_log_one_minus_is_ok);
251+
252+ result_is_ok = (result_log_one_minus_is_ok && result_is_ok);
253+ }
254+
255+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
256+ {
257+ static_cast <void >(index);
258+
259+ const auto log_inf = log10 (::my_inf<decimal_type>() * static_cast <decimal_type>(dist (gen)));
260+
261+ const volatile auto result_log_inf_is_ok = isinf (log_inf);
262+
263+ BOOST_TEST (result_log_inf_is_ok);
264+
265+ result_is_ok = (result_log_inf_is_ok && result_is_ok);
266+ }
267+
268+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
269+ {
270+ static_cast <void >(index);
271+
272+ const auto log_inf_minus = log10 (-::my_inf<decimal_type>() * static_cast <decimal_type>(dist (gen)));
273+
274+ const volatile auto result_log_inf_minus_is_ok = isnan (log_inf_minus);
275+
276+ BOOST_TEST (result_log_inf_minus_is_ok);
277+
278+ result_is_ok = (result_log_inf_minus_is_ok && result_is_ok);
279+ }
280+
281+ for (auto index = static_cast <unsigned >(UINT8_C (0 )); index < static_cast <unsigned >(UINT8_C (4 )); ++index)
282+ {
283+ static_cast <void >(index);
284+
285+ const auto log_nan = log10 (std::numeric_limits<decimal_type>::quiet_NaN () * static_cast <decimal_type>(dist (gen)));
286+
287+ const volatile auto result_log_nan_is_ok = isnan (log_nan);
288+
289+ BOOST_TEST (result_log_nan_is_ok);
290+
291+ result_is_ok = (result_log_nan_is_ok && result_is_ok);
292+ }
293+
294+ return result_is_ok;
295+ }
296+
185297} // namespace local
186298
187299auto main () -> int
@@ -194,6 +306,8 @@ auto main() -> int
194306
195307 const auto test_log10_is_ok = local::test_log10<decimal_type, float_type>(128 );
196308
309+ BOOST_TEST (test_log10_is_ok);
310+
197311 result_is_ok = (test_log10_is_ok && result_is_ok);
198312 }
199313
@@ -203,10 +317,53 @@ auto main() -> int
203317
204318 const auto test_log10_pow10_is_ok = local::test_log10_pow10<decimal_type, float_type>();
205319
320+ BOOST_TEST (test_log10_pow10_is_ok);
321+
206322 result_is_ok = (test_log10_pow10_is_ok && result_is_ok);
207323 }
208324
325+ {
326+ using decimal_type = boost::decimal::decimal32;
327+ using float_type = float ;
328+
329+ const auto test_log10_edge_is_ok = local::test_log10_edge<decimal_type, float_type>();
330+
331+ BOOST_TEST (test_log10_edge_is_ok);
332+
333+ result_is_ok = (test_log10_edge_is_ok && result_is_ok);
334+ }
335+
209336 result_is_ok = ((boost::report_errors () == 0 ) && result_is_ok);
210337
211338 return (result_is_ok ? 0 : -1 );
212339}
340+
341+ template <typename DecimalType>
342+ auto my_zero () -> DecimalType&
343+ {
344+ using decimal_type = DecimalType;
345+
346+ static decimal_type val_zero { 0 , 0 };
347+
348+ return val_zero;
349+ }
350+
351+ template <typename DecimalType>
352+ auto my_one () -> DecimalType&
353+ {
354+ using decimal_type = DecimalType;
355+
356+ static decimal_type val_one { 1 , 0 };
357+
358+ return val_one;
359+ }
360+
361+ template <typename DecimalType>
362+ auto my_inf () -> DecimalType&
363+ {
364+ using decimal_type = DecimalType;
365+
366+ static decimal_type val_inf { std::numeric_limits<decimal_type>::infinity () };
367+
368+ return val_inf;
369+ }
0 commit comments