@@ -123,28 +123,53 @@ constexpr auto pow(T b, IntegralType p) noexcept
123123 {
124124 result = one;
125125 }
126- else BOOST_DECIMAL_IF_CONSTEXPR (std::is_signed<local_integral_type>::value)
126+ else
127127 {
128- if (p < static_cast <local_integral_type>(UINT8_C (0 )))
128+ int exp10val { };
129+
130+ const auto bn { frexp10 (b, &exp10val) };
131+
132+ const auto
133+ zeros_removal
134+ {
135+ detail::remove_trailing_zeros (bn)
136+ };
137+
138+ const bool is_pure { static_cast <int >(zeros_removal.trimmed_number ) == 1 };
139+
140+ if (is_pure)
129141 {
130- const auto up =
131- static_cast <local_unsigned_integral_type>
132- (
133- static_cast <local_unsigned_integral_type>(~p)
134- + static_cast <local_unsigned_integral_type>(UINT8_C (1 ))
135- );
142+ // Here, a pure power-of-10 argument (b) gets a pure integral result.
143+ const int log10_val { exp10val + static_cast <int >(zeros_removal.number_of_removed_zeros ) };
136144
137- result = one / detail::pow_n_impl (b, up) ;
145+ result = T { 1 , static_cast < int >(log10_val * static_cast < int >(p)) } ;
138146 }
139147 else
140148 {
141- result = detail::pow_n_impl (b, static_cast <local_unsigned_integral_type>(p));
149+ BOOST_DECIMAL_IF_CONSTEXPR (std::is_signed<local_integral_type>::value)
150+ {
151+ if (p < static_cast <local_integral_type>(UINT8_C (0 )))
152+ {
153+ const auto up =
154+ static_cast <local_unsigned_integral_type>
155+ (
156+ static_cast <local_unsigned_integral_type>(~p)
157+ + static_cast <local_unsigned_integral_type>(UINT8_C (1 ))
158+ );
159+
160+ result = one / detail::pow_n_impl (b, up);
161+ }
162+ else
163+ {
164+ result = detail::pow_n_impl (b, static_cast <local_unsigned_integral_type>(p));
165+ }
166+ }
167+ else
168+ {
169+ result = detail::pow_n_impl (b, static_cast <local_unsigned_integral_type>(p));
170+ }
142171 }
143172 }
144- else
145- {
146- result = detail::pow_n_impl (b, static_cast <local_unsigned_integral_type>(p));
147- }
148173 }
149174
150175 return result;
0 commit comments