Untitled
system:sage

<p><strong>Benchmark 2</strong></p>
<p><strong> 
<table border="2" align="left">
<tbody>
<tr>
<td>Core 2</td>
<td>GMP</td>
<td><span style="font-size: medium;">MPIR</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Squaring</td>
<td>&nbsp;</td>
<td><br /></td>
</tr>
<tr>
<td><span style="font-weight: normal;">128 x 128&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">54446732</span></td>
<td><span style="font-weight: normal;">55370350</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">512 x 512&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">9320676</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">8172208</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 x 8192&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">104065</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">101386</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">131072 x 131072&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1620</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1722</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">2097152 x 2097152&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">70.1</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">76.7</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;Multiplication</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">128 x 128</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">54400830</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">55315582</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">512 x 512&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">7342969</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">8160125</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 x 8192&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">71306</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">75225</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">131072 x 131072&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1165</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1289</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">2097152 x 2097152&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">47.8</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">52.9</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Unbalanced</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">15000 x 10000&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">34790</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">36592</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">20000 x 10000&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">26612</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">28447</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">30000 x 10000&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">15707</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">16786</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">16777216 x 512&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">224</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">234</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">16777216 x 262144&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">9.01</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">9.89</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Division</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 / 32&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">807890</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">675542</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 / 64&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">801590</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">686421</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 / 128&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">527984</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">377947</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 / 4096&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">118750</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">110330</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 / 8064&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1651613</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1653280</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">131072 / 65536&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1382</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1371</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8388608 / 4194304&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">4.05</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">4.39</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">16777216 / 262144&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2.64</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2.80</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>GCD</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">128 x 128</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2172359</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2259180</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">512 x 512</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">236660</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">212043</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 x 8192</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">5846</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">5497</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">131072 x 131072</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">89.2</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">89.6</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">1048576 x 1048576</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">4.20</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">4.29</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>XGCD</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">128 x 128&nbsp;</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1028823</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">693319</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">512 x 512</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">176163</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">109519</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">8192 x 8192</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">3720</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2419</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">131072 x 131072</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">52.3</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">51.6</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">1048576 x 1048576</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2.81</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">2.57</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>RSA</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">512</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">16319</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">15019</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">1024</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">3048</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">3134</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">2048</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">482</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">479</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Pi</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;">10000</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">482</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">489</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">100000</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">20.7</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">22.7</span></td>
</tr>
<tr>
<td><span style="font-weight: normal;">1000000</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1.17</span></td>
<td style="text-align: right;"><span style="font-weight: normal;">1.32</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Overall</td>
<td style="text-align: right;">1065</td>
<td style="text-align: right;">1043</td>
</tr>
</tbody>
</table>
</strong></p>
<p><strong> 
<table border="2" align="left">
<tbody>
<tr>
<td>K8</td>
<td>GMP</td>
<td><span style="font-size: medium;">MPIR</span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Squaring</td>
<td>&nbsp;</td>
<td><br /></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">128 x 128&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">42226804</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td><span><span><span style="font-weight: normal;">53762100</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">512 x 512&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">10295600</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">12481800</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 x 8192&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">165214</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">168034</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">131072 x 131072&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2562</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2767</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">2097152 x 2097152&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">81.0</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">83.4</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;Multiplication</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">128 x 128</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">45649804</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">53767752</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">512 x 512&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">10913936</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">12428363</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 x 8192&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">114962</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">118476</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">131072 x 131072&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1754</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2075</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">2097152 x 2097152&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">52.3</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">63.3</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Unbalanced</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">15000 x 10000&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">57365</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">59908</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">20000 x 10000&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">44094</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">47322</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">30000 x 10000&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">24894</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">27565</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">16777216 x 512&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">345</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">332</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">16777216 x 262144&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">9.34</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">11.3</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Division</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 / 32&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1507178</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1319736</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 / 64&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1530848</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1319605</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 / 128&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">931519</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">478680</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 / 4096&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">189753</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">188476</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 / 8064&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2347446</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2333862</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">131072 / 65536&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2170</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">2229</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8388608 / 4194304&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">5.27</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">6.01</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">16777216 / 262144&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">4.12</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">4.46</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>GCD</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">128 x 128</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1436187</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1364651</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">512 x 512</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">227624</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">196581</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 x 8192</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">7833</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">6243</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">131072 x 131072</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">140</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">136</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">1048576 x 1048576</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">6.04</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">6.58</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>XGCD</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">128 x 128&nbsp;</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">910501</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">338531</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">512 x 512</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">173108</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">62580</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">8192 x 8192</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">5400</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">3007</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">131072 x 131072</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">84.8</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">82.4</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">1048576 x 1048576</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">3.88</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">4.08</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>RSA</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">512</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">20450</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">22476</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">1024</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">4152</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">5078</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">2048</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">783</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">882</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Pi</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">10000</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">644</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">652</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">100000</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">28.7</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">32.1</span></span><span style="font-weight: normal;"><br /></span></span></td>
</tr>
<tr>
<td><span style="font-weight: normal;"><span style="font-weight: normal;"><span style="font-weight: normal;">1000000</span></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1.42</span></span><span style="font-weight: normal;"><br /></span></span></td>
<td style="text-align: right;"><span><span><span style="font-weight: normal;">1.66</span></span><br /></span></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Overall</td>
<td style="text-align: right;">1435<br /></td>
<td style="text-align: right;">1446<br /></td>
</tr>
</tbody>
</table>
</strong></p>
<p><strong><span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;"><br /></span></strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2></h2>
<h2>Contributors</h2>
<ul>
<li>Jason Moxham - K8, Core2, Penryn, Nehalem, Pentium 4 assembly optimisation</li>
<li>Brian Gladman - MSVC port</li>
<li>Jason Martin - Core 2 assembly</li>
<li>Pierrick Gaudry - AMD 64 assembly</li>
<li>Anonymous Japanese contributor - assembly support</li>
<li>Robert Gerbicz - Root testing</li>
<li>William Hart - Sun, Apple, Cygwin, MSYS support, Toom 3/4/7 optimisation, Yasm switch, Fast Extended GCD</li>
<li>Paul Zimmermann, Marco Bodrato - Toom 4/7</li>
<li>Niels Moller - Fast GCD</li>
<li>Paul Zimmermann, Pierrick Gaudry, Alexander Kruppa, Torbjorn Granlund - Fermat/Mersenne FFT</li>
<li>Michael Abshoff - fix build issues, valgrinding, Sage integration</li>
<li>Mariah Lennox - work on mpirbench, build farm maintenance</li>
<li>Many others - contributions to build testing</li>
</ul>
<p>&nbsp;</p>
<h2>Fast Code in MPIR</h2>
<h3>At the mpz level</h3>
<p>&nbsp;</p>
<pre>struct
{
   mp_size_t _mp_size;
   mp_size_t _mp_alloc;
   mp_limb_t * _mp_data;
} __mpz_struct</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre>typedef mpz_t __mpz_struct[1];</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li>Checking for zero</li>
<p>Don't use mpz_cmp, use:</p>
<pre>if (mpz_sgn(a) == 0)</pre>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li>Combined multiplication and addition:</li>
<pre>mpz_addmul(x, a, b)</pre>
- set $x = x + ab$
<pre>mpz_submul(x, a, b)</pre>
- set $x = x - ab$
<pre>mpz_addmul_ui(x, a, b)</pre>
- set $x = x + ab$
<pre>mpz_submul_ui(x, a, b)</pre>
- set $x = x - ab$ 
</ul>
<p>&nbsp;</p>
<p>If you did the addition separately in addmul_ui it would take 40% longer!</p>
<p>&nbsp;</p>
<ul>
<li>Multiplication and division by powers of 2:</li>
<pre>mpz_mul_2exp(x, a, exp)</pre>
- set $x = 2^{exp}a$
<pre>mpz_tdiv_q_2exp(x, a, exp)</pre>
- set $x = a/2^{exp}$ 
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li>Exact division is faster than division with remainder:</li>
<pre>mpz_divexact(x, a, b)</pre>
- set $x = a/b$ assuming $b$ divides $a$
<pre>mpz_divexact_ui(x, a, b)</pre>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li>Don't use mpz_import or mpz_export</li>
<p>EVER!!</p>
</ul>
<p>&nbsp;</p>
<h2>MPIR Tools</h2>
<h3>GMP compatibility</h3>
<p>Use</p>
<pre>./configure --enable-gmpcompat</pre>
<p>and</p>
<pre>make install-gmpcompat</pre>
<p>if you wish to link MPIR against a library which is expecting GMP</p>
<p>&nbsp;</p>
<h3>Build from source - run make check</h3>
<p>Binaries will be slower - build from source. But always do "make check".</p>
<p>Many functions now support SSE, SSE2, SSE3, LAHF, etc, where available - binaries aren't built with all optimisations.</p>
<h3>Testing with make try</h3>
<p>In /tests/devel/ you can "make try"</p>
<p>DEMO</p>
<h3>Timing with make speed</h3>
<p>In /tune/ you can "make speed"</p>
<p>DEMO</p>
<h3>Performance tuning with make tune</h3>
<p>In /tune/ you can "make tune -f 1000000"</p>
<p>DEMO</p>
<h3>Developer documentation</h3>
<p>Some developer documentation is available in /doc/devel</p>
<h3>Fat binaries</h3>
<pre>./configure --enable-fat</pre>
<p>Fat binaries will pick best assembly core at runtime - but know that there is a performance deficit for small operands</p>
<h3>Enable asserts</h3>
<pre>./configure --enable-assert</pre>
<p>Can help with debugging code, whether at mpz/mpq/mpf or the mpn level.</p>
<h2>Enter the mpn's!</h2>
<h3>What is an mpn?</h3>
<p>An mpn is a pair</p>
<pre>{mp_limb_t * x, mp_size_t xn}</pre>
<p>where $x$ is an array of limbs, i.e. mp_limb_t's where $xn$ is the number of limbs, i.e. an mp_size_t. There is NO MEMORY MANAGEMENT done for you.</p>
<p>&nbsp;</p>
<p>Let's have a short example:</p>
<pre>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include "mpir.h"

int main(void)
{
   mp_limb_t * a, * b;
   a = malloc(1001*sizeof(mp_limb_t));
   b = malloc(1000*sizeof(mp_limb_t));

   mpn_random2(a, 1000);
   mpn_random2(b, 1000);
   a[1000] = 0;

   for (long i = 0; i &lt; 1000000; i++)
      a[1000] += mpn_addmul_1(a, b, 1000, 34567890);

   printf("a[1000] = %ld\n", a[1000]);

   free(a);
   free(b);

   return 0;
}
</pre>

<h2>New assembly functions in MPIR</h2>

<p>Lot's of new mpn functions are available on x86_64 in MPIR.</p>

<p><ul>
<li>mpn_divexact_by3(rp, sp, sn) - {rp, sn} computes {sp, sn} divided by 3 (carry is non-zero if exact division doesn't occur)</li>
<li>mpn_divexact_byBm1of(rp, sp, sn, f, (B-1)/f) computes {rp, sn} = {sp, sn} / f where f is a divisor of B-1, e.g. 5, 17, 15, 51, ....</li>
<li>mpn_addadd_n(rp, sp, tp, up, sn) computes cy, {rp, sn} = {sp, sn} + {tp, sn} + {up, sn}</li>
<li>mpn_addsub_n(rp, sp, tp, up, sn) computes cy, {rp, sn} = {sp, sn} + {tp, sn} - {up, sn}</li>
<li>mpn_subadd_n(rp, sp, tp, up, sn) computes bw, {rp, sn} = {sp, sn} - {(tp, sn} + {up, sn})</li>
<li>mpn_addlsh1_n(rp, sp, tp, sn) computes cy, {rp, sn} = {sp, sn} + 2{tp, sn}</li>
<li>mpn_sublsh1_n(rp, sp, tp, sn) computes br, {rp, sn} = {sp, sn} - 2{tp, sn}</li>
<li>mpn_mul_2(rp, sp, sn, cp) computes cy, {rp, sn + 1} = cp[0]{sp, sn} + cp[1]B{sp, tn}</li>
<li>mpn_addmul_2(rp, sp, sn, cp) computes cy, {rp, sn + 1} = {rp, sn + 1} + cp[0]{sp, sn} + cp[1]B{sp, tn}</li>
<li>mpn_sumdiff_n(rp, sp, tp, up, tn) computes cy, {rp, sn} = {tp, tn} + {up, tn} and bw, {sn, tn} = {tp, tn} - {up, tn} (function returns 2*cy+bw)</li>
<li>mpn_mul_basecase(rp, sp, sn, tp, tn) computes {rp, sn + tn} = {sp, sn} * {tp, tn}</li>
<li>mpn_sqr_basecase(rp, sp, sn) computes {rp, 2*sn} = {sp, sn} * {sp, sn}</li>
</ul>
</p>

<p>Also functions for and, andn, ior, iorn, nand, nior, xor, xnor and redc_basecase.</p>

<h2>ASSERTS</h2>

<p><ul>
<li>ASSERT(condition) will raise an assert if the condition is not met</li>
<li>ASSERT_ALWAYS(condition) will always check the condition, even when asserts are not enabled</li>
<li>ASSERT_CARRY(mpn_blah(...)) will assert that the function should return a nonzero carry</li>
<li>ASSERT_NOCARRY(mpn_blah(...)) asserts that the function should return a zero carry - useful for mpn_divexact_1, mpn_divexact_by3, etc</li>
<li>ASSERT_CODE(expr) for rolling your own assert code, i.e. expr can be anything, not just a condition</li>
<li>ASSERT_MPN_ZERO_P(ptr, size) asserts that the given mpn is zero (size equal to 0 is allowed)</li>
<li>ASSERT_MPN_NONZERO_P(ptr,size) assert that the given mpn is nonzero</li>
</ul></p>

<h2>MACROS</h2>
<p><ul>
<li>MPN_CMP(result, xp, yp, size) sets result to -ve, 0 or +ve depending on whether {xp, size} is less than equal to or greater than {yp, size}, leading zero limbs are allowed</li>
<li>ABS(xn), MIN(xn, yn), MAX(xn, yn) - just what they say</li>
<li>POW2_P(n) - whether n is an exact power of 2 (or zero)</li>
<li>MPN_PTR_SWAP(x, xn, y, yn) - swaps {x, xn} and {y, yn} by swapping the pointers x, y and the lengths xn, yn, not the data</li>
<li>MPN_SRCPTR_SWAP(xp, xn, yp, yn) - for swapping mpn's which are source operands, i.e. those basically declared const</li>
<li>MP_SIZE_T_SWAP (xn, yn) - swap two mp_size_t's</li>
<li>MPN_COPY(d, s, n) - copy {s, n} to {d, n}</li>
<li>MPN_COPY_INCR(d, s, n) - copy {s, n} to {d, n} incrementing memory locations as the copy proceeds</li>
<li>MPN_COPY_DECR(d, s, n) - copy {s, n} to {d, n} decrementing memory locations as the copy proceeds</li>
<li>MPN_SAME_OR_SEPARATE_P (d, s, n) returns nonzero if the mpns {d, n} and {s, n} are either the same or completely non-overlapping</li>
<li>MPN_SAME_OR_INCR_P (d, s, n) returns nonzero if the mpns are the same or if it would be safe to copy one to the other whilst incrementing memory locations</li>
<li>MPN_SAME_OR_DECR_P (d, s, n) returns nonzero if the mpns are the same or if it would be safe to copy one to the other whilst decrementing memory locations</li>
<li>MPN_OVERLAP_P (d, dn, s, sn) returns nonzero if {d, dn} overlaps {s, sn}</li>
<li>MPN_REVERSE(d, s, n) set {d, n} to the reverse of {s, n}</li>
<li>MPN_NORMALIZE(d, dn) normalises the mpn {d, dn} - note you have to start with dn as an upper bound on the number of limbs with possible zero leading limbs</li>
<li>MPN_NORMALIZE_NOT_ZERO(d, dn) - same as MPN_NORMALIZE except that it assumes the final dn will not be zero</li>
<li>MPN_STRIP_LOW_ZEROS_NOT_ZERO(s, sn, low) - start with low equal to s[0], this function will increment s and decrement sn until s[0] is nonzero and it will set low to the new s[0], assumes that {s, sn} is not zero</li> 
<li>MPN_LOGOPS_N_INLINE(d, s1, s2, n, operation) - applies the given operation between the limbs of {s1, n} and {s2, n} and sets d to the result, e.g. <pre>MPN_LOGOPS_N_INLINE(d, s1, s2, n, d[__n] = s1[__n] & s2[__n])</pre></li>
<li>MPN_ZERO(s, sn) - set {s, sn} to zero</li>
<li>mpn_store(d, n, val) - set all limbs of {d, n} to val</li>
<li>mpn_com_n(d, s, n) - set {d, n} to the twos complement of {s, n}</li>
<li>ADDC_LIMB(cy, w, x, y) - set cy, w = x + y where x and y are limbs</li>
<li>SUBC_LIMB(bw, w, x, y) - set bw, w = x - y where x and y are limbs</li>
<li>LIMB_HIGHBIT_TO_MASK(n)  - returns a limb of all 1's if n has its top bit set, otherwise returns 0</li>
<li>MPN_INCR_U(s, sn, incr) - set {s, sn} = {s, sn} + incr where incr is a single limb (assuming no carry)</li> 
<li>MPN_DECR_U(s, sn, incr) - set {s, sn} = {s, sn} - incr where incr is a single limb (assuming no borrow)</li>
</ul></p>

<h2>HINTS</h2>
<p><ul>
<li>if LIKELY(condition) - will give a hint to the CPU that the branch is likely to be taken</li>
<li>if UNLIKELY(condition) - will give a hint to the CPU that the branch is unlikely to be taken</li>
</ul>
</p>

<h2>Temporary allocation</h2>
<p>MPIR has a temporary memory allocation system, like Pari. Here is an example of it in action:</p>

<pre>
mp_limb_t * ws;

TMP_DECL;

/* do whatever */

TMP_MARK;
ws = TMP_ALLOC_LIMBS (count);
      
/* Use ws however you like */

TMP_FREE;
</pre>

<p>The temporary allocation allocates memory on the stack if it is a small quantity and on the heap if it is big. But if you know you always want a small amount use TMP_SDECL, TMP_SMARK, TMP_SALLOC_LIMBS, TMP_SFREE. If you know you need a big amount all the time, or you want to avoid the stack overflowing, use TMP_BDECL, TMP_BMARK, TMP_BALLOC_LIMBS, TMP_BFREE.</p>

<h3>Two's complement</h3>
<p>One can use mpn's for negative numbers by making use of two's complement format and working to a fixed precision where overflow can't occur.</p>

<p>Here is a specific example. We pass in three mpn's to a function, all of the same length, assuming the first two are positive and the third is signed. We also suppose the top limb of each is zero upon entry.</p>

<pre>
void myfunction(mp_limb_t rp, mp_size_t * rn, mp_limb_t sp, mp_limb_t up, mp_limb_t vp, mp_size_t sn)
{
   mp_size_t size = ABS(sn);

   mpn_add_n(sp, sp, up, size);

   if (sn < 0) 
      mpn_add_n(vp, sp, vp, size);
   else
      mpn_sub_n(vp, sp, vp, size);
   /* vp is now in twos complement format */

   mpn_lshift1(vp, vp, size);

   mpn_submul_1(rp, vp, size, 64);
}
</pre>

<p>BEWARE: right shift doesn't necessarily work because the sign bit will be shifted right. However one can use MPN_HIGH_BIT_TO_MASK to fix the top bits. Multiplication, division and divexact won't work on two's complement, so one needs to make the mpn's unsigned first, e.g. do mpn_com_n(sp, sp, size) and mpn_add_1(sp, sp, size, 1) to negate them if negative.</p>

<h3>Memory management savings</h3>

<p>Saving memory can make a huge difference in algorithms where caching becomes important. Here are some tips:</p>

<ul>
<li>Break large computations up into smaller chunks to improve locality - only helps if you use the same data over and over</li>
<li>Allocate as little temporary memory as possible</li>
<li>Try using some of the output space for temporary storage during the computation - this can also save a copy of data at the end of the computation if part of the result happens to end up in the right place</li>
<li>In some cases it is possible to store everything except for carry limbs, which overlap some other temporary space. It is often more efficient to make a copy of the small bit that would be overlapped by the carry limbs, and add it back in later, than to allocate a large temporary space and copy the whole result over when done.</li>
</li>
</ul>

<h3>Using longlong.h</h3>

<p>Ever wanted to get carries in C? Use longlong.h in the top level source directory of MPIR.</p>

<p>WARNING: just doing</p>
<pre>#include "longlong.h"</pre>
<p>is not enough, and will return <ul><b>WRONG ANSWERS</b></ul> on some platforms.</p>

<p>One either has to first include gmp-impl.h or one has to do something like the following (works on all C99 systems we know of):</p>

<pre>
#include <stdint.h>

#define UWtype mp_limb_t
#define UHWtype mp_limb_t
#define UDWtype mp_limb_t 
#define W_TYPE_SIZE {insert number of bits of UWtype here}
#define SItype int32_t
#define USItype uint32_t
#define DItype int64_t
#define UDItype uint64_t

#define LONGLONG_STANDALONE

#define ASSERT(condition)

#include "longlong.h"
</pre>

<p>On a machine where a limb is two unsigned longs, you might set UDWtype to mp_limb_t and UWtype and UHWtype to unsigned long. You can define UHWtype to be half the size of UWtype if you want. You can define ASSERT to be whatever you want, but it must be defined. On a 32 bit machine UWtype should typically be USItype; on a 64 bit machine, UWtype should typically be UDItype</p>

<p>Once we have longlong.h included we have access to the following functions:</p>

<p><ul>
<li>umul_ppmm(high_prod, low_prod, multipler, multiplicand) - multiplication of two UWtypes, returning high and low limbs</li>
<li>__umulsidi3(a,b) - multiply two UWtypes, returning a single UDWtype</li>
<li>udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) - division returning quotient and remainder. On some systems the high bit of denominator must be 1. If so, longlong.h sets UDIV_NEEDS_NORMALIZATION to 1.</li>
<li>sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) - as for udiv_qrnnd, but with signed integers - quotient is rounded towards zero.</li>
<li>count_leading_zeros(count, x) - sets count to the number of leading zeroes of x. It sets count to COUNT_LEADING_ZEROS_0 if x is 0. You must define that macro if you wish to use it.</li>
<li>count_trailing_zeros(count, x) - as for count_leading_zeros, but counts the trailing zeroes.</li>
<li>add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, high_addend_2, low_addend_2) - add two 2 limb quantities</li>
<li>sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, high_subtrahend, low_subtrahend) - subtract two 2 limb quantities</li>

{{{id=1|

///
}}}