Skip to content

Commit

Permalink
A note on smaller divisors
Browse files Browse the repository at this point in the history
  • Loading branch information
purplesyringa committed Aug 24, 2024
1 parent 156cac1 commit b5a8468
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<span class=hljs-keyword>lea</span> <span class=hljs-built_in>rcx</span>, [<span class=hljs-built_in>rax</span> + <span class=hljs-number>59</span>]
<span class=hljs-keyword>cmovb</span> <span class=hljs-built_in>rax</span>, <span class=hljs-built_in>rcx</span>
<span class=hljs-keyword>ret</span>
</code></pre><hr><p>Oh, and it’s not like hard-coding <eq><math><mrow><msup><mn>2</mn><mn>64</mn></msup><mo></mo></mrow><mrow><mn>59</mn></mrow></math></eq> was necessary. Two iterations suffice for any divisor <eq><math><mrow><mo></mo></mrow><mrow><msup><mn>2</mn><mn>64</mn></msup><mo></mo></mrow><mrow><msup><mn>2</mn><mn>32</mn></msup><mo>+</mo></mrow><mrow><mn>1</mn></mrow></math></eq>. Need more primes? Choose away, there’s a lot of them in the <eq><math><msup><mn>2</mn><mn>32</mn></msup></math></eq>-long region.<p>And this method works for division too, not just modulo:<pre><code class=language-rust><span class=hljs-keyword>fn</span> <span class="hljs-title function_">divide</span>(<span class=hljs-keyword>mut</span> n: <span class=hljs-type>u128</span>) <span class=hljs-punctuation>-></span> <span class=hljs-type>u128</span> {
</code></pre><hr><p>Oh, and it’s not like hard-coding <eq><math><mrow><msup><mn>2</mn><mn>64</mn></msup><mo></mo></mrow><mrow><mn>59</mn></mrow></math></eq> was necessary. Two iterations suffice for any divisor <eq><math><mrow><mo></mo></mrow><mrow><msup><mn>2</mn><mn>64</mn></msup><mo></mo></mrow><mrow><msup><mn>2</mn><mn>32</mn></msup><mo>+</mo></mrow><mrow><mn>1</mn></mrow></math></eq>. Need more primes? Choose away, there’s a lot of them in the <eq><math><msup><mn>2</mn><mn>32</mn></msup></math></eq>-long region.<p>Need a smaller divisor? Three iterations work for <eq><math><mrow><mi>n</mi><mo></mo></mrow><mrow><msup><mn>2</mn><mn>64</mn></msup><mo></mo></mrow><mrow><mn>6981461082631</mn></mrow></math></eq> (42.667 bits compared to 32 for two iterations), four for <eq><math><mrow><mi>n</mi><mo></mo></mrow><mrow><msup><mn>2</mn><mn>64</mn></msup><mo></mo></mrow><mrow><mn>281472113362716</mn></mrow></math></eq> (48 bits). Sounds like a lot? That’s still better than <code>__umodti3</code>.<p>And this method works for division too, not just modulo:<pre><code class=language-rust><span class=hljs-keyword>fn</span> <span class="hljs-title function_">divide</span>(<span class=hljs-keyword>mut</span> n: <span class=hljs-type>u128</span>) <span class=hljs-punctuation>-></span> <span class=hljs-type>u128</span> {
<span class=hljs-keyword>let</span> <span class=hljs-keyword>mut </span><span class=hljs-variable>quotient</span> = n >> <span class=hljs-number>64</span>;
n = n % (<span class=hljs-number>1</span> << <span class=hljs-number>64</span>) + (n >> <span class=hljs-number>64</span>) * <span class=hljs-number>59</span>;
quotient += n >> <span class=hljs-number>64</span>;
Expand Down
2 changes: 2 additions & 0 deletions blog/division-is-hard-but-it-does-not-have-to-be/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ modulo:

Oh, and it's not like hard-coding $2^{64} - 59$ was necessary. Two iterations suffice for any divisor $\ge 2^{64} - 2^{32} + 1$. Need more primes? Choose away, there's a lot of them in the $2^{32}$-long region.

Need a smaller divisor? Three iterations work for $n \ge 2^{64} - 6981461082631$ (42.667 bits compared to 32 for two iterations), four for $n \ge 2^{64} - 281472113362716$ (48 bits). Sounds like a lot? That's still better than `__umodti3`.

And this method works for division too, not just modulo:

```rust
Expand Down

0 comments on commit b5a8468

Please sign in to comment.