 <p>The idea is to use following fact which is true for integral operation:</p> <p><code>a*b &gt; c</code> if and only if <code>a &gt; c/b</code></p> <p><code>/</code> is integral division here.</p> <p>The pseudocode to check against overflow for positive numbers follows:</p> <p><strong>if (a > max_int64 / b) then "overflow" else "ok"</strong>.</p> <p>To handle zeroes and negative numbers you should add more checks.</p> <p>C code for non-negative <code>a</code> and <code>b</code> follows:</p> <pre><code>if (b &gt; 0 &amp;&amp; a &gt; 18446744073709551615 / b) { // overflow handling }; else { c = a * b; } </code></pre> <p>Note: </p> <pre><code>18446744073709551615 == (1&lt;&lt;64)-1 </code></pre> <p>To calculate carry we can use approach to split number into two 32-digits and multiply them as we do this on the paper. We need to split numbers to avoid overflow.</p> <p>Code follows:</p> <pre><code>// split input numbers into 32-bit digits uint64_t a0 = a &amp; ((1LL&lt;&lt;32)-1); uint64_t a1 = a &gt;&gt; 32; uint64_t b0 = b &amp; ((1LL&lt;&lt;32)-1); uint64_t b1 = b &gt;&gt; 32; // The following 3 lines of code is to calculate the carry of d1 // (d1 - 32-bit second digit of result, and it can be calculated as d1=d11+d12), // but to avoid overflow. // Actually rewriting the following 2 lines: // uint64_t d1 = (a0 * b0 &gt;&gt; 32) + a1 * b0 + a0 * b1; // uint64_t c1 = d1 &gt;&gt; 32; uint64_t d11 = a1 * b0 + (a0 * b0 &gt;&gt; 32); uint64_t d12 = a0 * b1; uint64_t c1 = (d11 &gt; 18446744073709551615 - d12) ? 1 : 0; uint64_t d2 = a1 * b1 + c1; uint64_t carry = d2; // needed carry stored here </code></pre>