{"id":17,"date":"2006-07-02T10:52:27","date_gmt":"2006-07-02T18:52:27","guid":{"rendered":"http:\/\/www.pagetable.com\/?p=17"},"modified":"2006-07-02T10:52:27","modified_gmt":"2006-07-02T18:52:27","slug":"win32s-muldiv","status":"publish","type":"post","link":"https:\/\/www.pagetable.com\/?p=17","title":{"rendered":"Win32&#039;s MulDiv"},"content":{"rendered":"<p>In Win32, there is an API call called &#8220;MulDiv&#8221;:<\/p>\n<p>The MulDiv function multiplies two 32-bit values and then divides the  64-bit result by a third 32-bit value. The return value is rounded up or down to  the nearest integer.<\/p>\n<p>int WINAPI MulDiv(<br \/>\nint nNumber,<br \/>\nint nNumerator,<br \/>\nint nDenominator<br \/>\n);<\/p>\n<p>If a divide overflow (including divide by zero) occurs, MulDiv returns -1.  (Stupidly, there&#8217;s no way to actually check whether the result truly is -1 instead of an error.)<\/p>\n<p>How do we implement this in x86-32?  The official version does not use structured exception handling to simply catch the exception and handle it.  MulDiv actually checks for overflow beforehand and never causes an exception.<\/p>\n<p>The official implementation is several pages long, and I think we could do much better.<\/p>\n<p>If this were the unsigned case, the entire function would be simple:<\/p>\n<p>mov eax, [esp+4]<br \/>\nmul dword ptr [esp+8]<br \/>\ncmp edx, [esp+12]<br \/>\njae overflow<br \/>\ndiv dword ptr [esp+12]<br \/>\nret 12<br \/>\noverflow:<br \/>\nor eax, -1<br \/>\nret 12<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Win32, there is an API call called &#8220;MulDiv&#8221;: The MulDiv function multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value. The return value is rounded up or down to the nearest integer. int WINAPI MulDiv( int nNumber, int nNumerator, int nDenominator ); If a divide overflow (including divide &#8230; <a title=\"Win32&#039;s MulDiv\" class=\"read-more\" href=\"https:\/\/www.pagetable.com\/?p=17\" aria-label=\"Read more about Win32&#039;s MulDiv\">Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-17","post","type-post","status-publish","format-standard","hentry","category-puzzle"],"_links":{"self":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/17","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17"}],"version-history":[{"count":0,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/17\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=17"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=17"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}