Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If <code>x</code> is our input...</p> <p>If <code>x &gt; INT_MAX</code>, we want to find a constant <code>k</code> such that <code>0</code> &lt; <code>x - k*INT_MAX</code> &lt; <code>INT_MAX</code>.</p> <p>This is easy -- <code>unsigned int k = x / INT_MAX;</code>. Then, let <code>unsigned int x2 = x - k*INT_MAX;</code></p> <p>We can now cast <code>x2</code> to <code>int</code> safely. Let <code>int x3 = static_cast&lt;int&gt;(x2);</code></p> <p>We now want to subtract something like <code>UINT_MAX - k * INT_MAX + 1</code> from <code>x3</code>, if <code>k &gt; 0</code>.</p> <p>Now, on a 2s complement system, so long as <code>x &gt; INT_MAX</code>, this works out to:</p> <pre><code>unsigned int k = x / INT_MAX; x -= k*INT_MAX; int r = int(x); r += k*INT_MAX; r -= UINT_MAX+1; </code></pre> <p>Note that <code>UINT_MAX+1</code> is zero in C++ guaranteed, the conversion to int was a noop, and we subtracted <code>k*INT_MAX</code> then added it back on "the same value". So an acceptable optimizer should be able to erase all that tomfoolery!</p> <p>That leaves the problem of <code>x &gt; INT_MAX</code> or not. Well, we create 2 branches, one with <code>x &gt; INT_MAX</code>, and one without. The one without does a strait cast, which the compiler optimizes to a noop. The one with ... does a noop after the optimizer is done. The smart optimizer realizes both branches to the same thing, and drops the branch.</p> <p>Issues: if <code>UINT_MAX</code> is really large relative to <code>INT_MAX</code>, the above might not work. I am assuming that <code>k*INT_MAX &lt;= UINT_MAX+1</code> implicitly.</p> <p>We could probably attack this with some enums like:</p> <pre><code>enum { divisor = UINT_MAX/INT_MAX, remainder = UINT_MAX-divisor*INT_MAX }; </code></pre> <p>which work out to 2 and 1 on a 2s complement system I believe (are we guaranteed for that math to work? That's tricky...), and do logic based on these that easily optimize away on non-2s complement systems...</p> <p>This also opens up the exception case. It is only possible if UINT_MAX is much larger than (INT_MIN-INT_MAX), so you can put your exception code in an if block asking exactly that question somehow, and it won't slow you down on a traditional system.</p> <p>I'm not exactly sure how to construct those compile-time constants to deal correctly with that.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload