* 1233 >> 12 在这个计算十进制数字的代码中背后的数学是什么
What is the math behind * 1233 >> 12 in this code counting decimal digits
我对这个 short function from the C++ {fmt} library 的工作原理有点困惑。
inline std::uint32_t digits10_clz(std::uint32_t n) {
std::uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12;
return t - (n < powers_of_10_u32[t]) + 1;
}
我理解您可以使用 log2(__builtin_clz)
来近似 log10
并且您需要调整精确值的逻辑,但乘法对我来说是个谜。
召回the formula for changing the base of logarithm从b
到d
是
logdx = logbx / logbd
在我们的例子中,b
是 2(二进制),d
是 10(十进制)。因此,您需要除以 log210,这与乘以 1/log210 相同,即乘以 0.30102999566.
现在回想一下,移动 12 等于除以 212,即 4096。将 1233 除以 4096 得到 0.30102539062,这是分母的一个很好的近似值在基础变化公式中。
我对这个 short function from the C++ {fmt} library 的工作原理有点困惑。
inline std::uint32_t digits10_clz(std::uint32_t n) {
std::uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12;
return t - (n < powers_of_10_u32[t]) + 1;
}
我理解您可以使用 log2(__builtin_clz)
来近似 log10
并且您需要调整精确值的逻辑,但乘法对我来说是个谜。
召回the formula for changing the base of logarithm从b
到d
是
logdx = logbx / logbd
在我们的例子中,b
是 2(二进制),d
是 10(十进制)。因此,您需要除以 log210,这与乘以 1/log210 相同,即乘以 0.30102999566.
现在回想一下,移动 12 等于除以 212,即 4096。将 1233 除以 4096 得到 0.30102539062,这是分母的一个很好的近似值在基础变化公式中。