在此代码中计算十进制数字的*1233 >> 12背后的数学是什么

NoS*_*tAl 5 c++ optimization unsigned bit-manipulation fmt

我对C++ fmtlib的这个简短函数如何工作有点困惑.

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;
}
Run Code Online (Sandbox Code Playgroud)

我理解你可以使用log2(log10)来估计log10的逻辑,并且你需要调整精确值,但乘法对我来说是一个谜.

das*_*ght 10

回想一下公式用于改变对数的底数bd

log d x = log b x/log b d

在我们的例子中,b是2(二进制),并且d是10(十进制).因此,您需要除以log 2 10,这与乘以1/log 2 10相同,即乘以0.30102999566.

现在回想一下,换算12与除以2 12相同,即4096.将1233除以4096得到0.30102539062,这是基本变化公式中分母的一个非常好的近似值.

  • @NickyC很难说 - 或许他们从[点滴技巧的来源](https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10)复制了这个,并且在那里写作的作者不信任编译器优化他的代码.我会毫不犹豫地替换师的转变. (2认同)
  • fmtlib的作者在这里:@dasblinkenlight正确地猜想该公式确实来自http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10,如评论https://github.com/fmtlib中所指出/fmt/blob/0f98773164415ef70eef35daedab115935692524/fmt/format.h#L1054 (2认同)