@@ -40,85 +40,84 @@ constexpr auto log10_impl(T x) noexcept
4040 {
4141 result = (!signbit (x)) ? x: std::numeric_limits<T>::quiet_NaN ();
4242 }
43- else if (x < one)
44- {
45- // Handle reflection, the [+/-] zero-pole, and non-pole, negative x.
46- if (x > zero)
47- {
48- result = -log10 (one / x);
49- }
50- else if ((x == zero) || (-x == zero))
51- {
52- // Actually, this should be equivalent to -HUGE_VAL.
53-
54- result = -std::numeric_limits<T>::infinity ();
55- }
56- else
57- {
58- result = std::numeric_limits<T>::quiet_NaN ();
59- }
60- }
61- else if (x > one)
43+ else
6244 {
63- // The algorithm for base-10 logarithm is based on Chapter 5, pages 35-36
64- // of Cody and Waite, Software Manual for the Elementary Functions,
65- // Prentice Hall, 1980.
66-
6745 int exp10val { };
6846
6947 T g { frexp10 (x, &exp10val) };
7048
7149 while (g > one)
7250 {
73- // TODO(ckormanyos) Do we really have to multiply individual powers
74- // of 10 here? Or is there a reliable way to simply use pow10()?
75- // For instance count intagral orders of exp10val and divide by pow10().
76-
77- g /= 10 ;
51+ g /= 10 ;
7852
79- ++exp10val;
53+ ++exp10val;
8054 }
8155
82- if (g == one)
56+ const bool is_pure = (g == one);
57+
58+ if (is_pure)
8359 {
8460 result = T { exp10val };
8561 }
8662 else
8763 {
88- constexpr T inv_sqrt10 { UINT64_C (3162277660168379332 ), -19 };
64+ if (x < one)
65+ {
66+ // Handle reflection, the [+/-] zero-pole, and non-pole, negative x.
67+ if (x > zero)
68+ {
69+ result = -log10 (one / x);
70+ }
71+ else if ((x == zero) || (-x == zero))
72+ {
73+ // Actually, this should be equivalent to -HUGE_VAL.
74+
75+ result = -std::numeric_limits<T>::infinity ();
76+ }
77+ else
78+ {
79+ result = std::numeric_limits<T>::quiet_NaN ();
80+ }
81+ }
82+ else if (x > one)
83+ {
84+ // The algorithm for base-10 logarithm is based on Chapter 5, pages 35-36
85+ // of Cody and Waite, Software Manual for the Elementary Functions,
86+ // Prentice Hall, 1980.
87+ constexpr T inv_sqrt10 { UINT64_C (3162277660168379332 ), -19 };
8988
90- const bool reduce_sqrt10 { g < inv_sqrt10 };
89+ const bool reduce_sqrt10 { g < inv_sqrt10 };
9190
92- if (reduce_sqrt10)
93- {
94- constexpr T sqrt10 { UINT64_C (3162277660168379332 ), -18 };
91+ if (reduce_sqrt10)
92+ {
93+ constexpr T sqrt10 { UINT64_C (3162277660168379332 ), -18 };
9594
96- g *= sqrt10;
97- }
95+ g *= sqrt10;
96+ }
9897
99- const T s { (g - one) / (g + one) };
100- const T z { s + s };
101- const T zsq { z * z };
98+ const T s { (g - one) / (g + one) };
99+ const T z { s + s };
100+ const T zsq { z * z };
102101
103- result = z * fma (detail::log_series_expansion (zsq), zsq, one);
102+ result = z * fma (detail::log_series_expansion (zsq), zsq, one);
104103
105- result /= numbers::ln10_v<T>;
104+ result /= numbers::ln10_v<T>;
106105
107- if (reduce_sqrt10)
108- {
109- constexpr T half { 5 , -1 };
106+ if (reduce_sqrt10)
107+ {
108+ constexpr T half { 5 , -1 };
110109
111- result -= half;
112- }
110+ result -= half;
111+ }
113112
114- result += static_cast <T>(exp10val);
113+ result += static_cast <T>(exp10val);
114+ }
115+ else
116+ {
117+ result = zero;
118+ }
115119 }
116120 }
117- else
118- {
119- result = zero;
120- }
121-
122121 return result;
123122}
124123
0 commit comments