TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Computing the number of digits of an integer even faster

103 点作者 vitaut将近 4 年前

14 条评论

silvestrov将近 4 年前
The big table becomes more obvious when the constants are written using hex:<p><pre><code> static uint64_t table[] = { 0x100000000, 0x1FFFFFFF6, 0x1FFFFFFF6, 0x1FFFFFFF6, 0x2FFFFFF9C, 0x2FFFFFF9C, 0x2FFFFFF9C, 0x3FFFFFC18, 0x3FFFFFC18, 0x3FFFFFC18, 0x4FFFFD8F0, 0x4FFFFD8F0, 0x4FFFFD8F0, 0x4FFFFD8F0, 0x5FFFE7960, 0x5FFFE7960, 0x5FFFE7960, 0x6FFF0BDC0, 0x6FFF0BDC0, 0x6FFF0BDC0, 0x7FF676980, 0x7FF676980, 0x7FF676980, 0x7FF676980, 0x8FA0A1F00, 0x8FA0A1F00, 0x8FA0A1F00, 0x9C4653600, 0x9C4653600, 0x9C4653600, 0xA00000000, 0xA00000000, };</code></pre>
评论 #27394977 未加载
spatulon将近 4 年前
Here&#x27;s one interesting application of a digit-count function.<p>The naive implementation of an integer-to-string conversion involves writing the number backwards, starting from the least significant digit, and then reversing the string at the end.<p>In a 2017 talk titled &quot;Fastware&quot;[1], Andrei Alexandrescu showed that it&#x27;s faster to start by counting the number of digits you&#x27;re going to print, and then you can print by working backwards from the least significant digit. It comes out in the correct order without any need to reverse at the end.<p>His implementation of the digit count was itself interesting, since it does 4 comparisons per loop and then a divide by 10000, instead of the naive single comparison and divide by 10.<p><pre><code> uint32_t digits10(uint64_t v) { uint32_t result = 1; for (;;) { if (v &lt; 10) return result; if (v &lt; 100) return result + 1; if (v &lt; 1000) return result + 2; if (v &lt; 10000) return result + 3; v &#x2F;= 10000U; result += 4; } } </code></pre> IIRC, his insight was that smaller numbers tend to occur more often in the real world, so most calls to this function will not end up doing any divisions.<p>[1] <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=o4-CwDo2zpg" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=o4-CwDo2zpg</a>
评论 #27397903 未加载
评论 #27398209 未加载
评论 #27397151 未加载
评论 #27411886 未加载
评论 #27396700 未加载
评论 #27398322 未加载
chrisseaton将近 4 年前
This blog post is a response to another blog post which is a response to a question about how to implement integer-to-string length as quickly as possible in an optimising implementation of the Ruby programming language called TruffleRuby, if people here wanted a concrete example of how these kind of brain-teasers come up for real in industrial programming in an everyday job.
Zamicol将近 4 年前
I sometimes have difficulty finding efficient algorithms for specific tasks like this. Any advice on becoming better at finding efficient algorithms?
评论 #27396682 未加载
评论 #27395332 未加载
评论 #27395461 未加载
评论 #27399751 未加载
h2odragon将近 4 年前
<p><pre><code> Digits = LEN( STR$( SomeNumber )) </code></pre> (<i>run and hide in shame</i>)
评论 #27396312 未加载
openasocket将近 4 年前
Awesome find! But I wonder how easily this could be extended to 64 bit integers? That sequence in the lookup table won&#x27;t fit into 64 bits if it&#x27;s extended. I think you would have to fall back to just having the lookup table storing the transition data, as described in <a href="https:&#x2F;&#x2F;commaok.xyz&#x2F;post&#x2F;lookup_tables&#x2F;" rel="nofollow">https:&#x2F;&#x2F;commaok.xyz&#x2F;post&#x2F;lookup_tables&#x2F;</a> in the &quot;A Small Step&quot; section. And probably add a conditional in the beginning to handle very large integers that would overflow. Alternatively you might be able to do something with two lookup tables, but I think at that point you&#x27;ve got enough lookup data that it would be less efficient.
评论 #27396883 未加载
评论 #27400310 未加载
评论 #27397778 未加载
failwhaleshark将近 4 年前
I recall needing this on a snprintf() implementation.<p>Isn&#x27;t this effectively a table-optimized logBase(x) rounded-up to the ceiling, which can be reduced to efficient log2(x)&#x2F;log2(Base)? If you know the base, then you can combine many ops into table-lookups.<p>As an exercise to the reader, I suggest creating efficient code constrained to 32-bit or 16-bit unsigned.<p>PS: I was going to say &quot;look at <i>Hacker&#x27;s Delight</i>.&quot; I can definitely read. LOL.
detay将近 4 年前
it all goes back to 650x, where we had no multiplication&#x2F;division and we had to create sin&#x2F;cos tables.
评论 #27395046 未加载
FartyMcFarter将近 4 年前
It&#x27;d be interesting to see a performance benchmark of the various solutions, including ones that don&#x27;t use lookup tables.<p>The results of such a benchmark would probably heavily depend on whether the lookup table is allowed to be in the CPU caches.
LordGrey将近 4 年前
Is there a version of this that would tell you the number of bytes an integer would use? If so, how would it differ with signed versus unsigned integers?
评论 #27403602 未加载
gameswithgo将近 4 年前
No way to leverage popcount instruction for this?
评论 #27399864 未加载
评论 #27395190 未加载
评论 #27395087 未加载
Bayart将近 4 年前
A few days ago I had to write a bit of code in C# with an int to string conversion, and since I never use that language and I&#x27;m not used to OOP I completely looked over the ToString() method every primitive type has, I wrote a dumb conversion like I used to do as a student in C. The basic modulo 10 loop thing. You know the one.<p>Anyway I&#x27;m glad to know there&#x27;s a cool lookup table trick out there, I never really get to use anything like that but it makes for a nice read.
jedberg将近 4 年前
This is a fun optimization, but what is a use case where I would need to count the number of digits?
评论 #27398988 未加载
toolslive将近 4 年前
you can also base your solution on hamilton cycles. that also boils down to o(1).
评论 #27395335 未加载