Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7028643
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T00:26:11+00:00 2026-05-28T00:26:11+00:00

What is the most accurate way I can do a multiply-and-divide operation for 64-bit

  • 0

What is the most accurate way I can do a multiply-and-divide operation for 64-bit integers that works in both 32-bit and 64-bit programs (in Visual C++)? (In case of overflow, I need the result mod 264.)

(I’m looking for something like MulDiv64, except that this one uses inline assembly, which only works in 32-bit programs.)

Obviously, casting to double and back is possible, but I’m wondering if there’s a more accurate way that isn’t too complicated. (i.e. I’m not looking for arbitrary-precision arithmetic libraries here!)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T00:26:11+00:00Added an answer on May 28, 2026 at 12:26 am

    Since this is tagged Visual C++ I’ll give a solution that abuses MSVC-specific intrinsics.

    This example is fairly complicated. It’s a highly simplified version of the same algorithm that is used by GMP and java.math.BigInteger for large division.

    Although I have a simpler algorithm in mind, it’s probably about 30x slower.

    This solution has the following constraints/behavior:

    • It requires x64. It will not compile on x86.
    • The quotient is not zero.
    • The quotient saturates if it overflows 64-bits.

    Note that this is for the unsigned integer case. It’s trivial to build a wrapper around this to make it work for signed cases as well. This example should also produce correctly truncated results.

    This code is not fully tested. However, it has passed all the tests cases that I’ve thrown at it.
    (Even cases that I’ve intentionally constructed to try to break the algorithm.)

    #include <intrin.h>
    
    uint64_t muldiv2(uint64_t a, uint64_t b, uint64_t c){
        //  Normalize divisor
        unsigned long shift;
        _BitScanReverse64(&shift,c);
        shift = 63 - shift;
    
        c <<= shift;
    
        //  Multiply
        a = _umul128(a,b,&b);
        if (((b << shift) >> shift) != b){
            cout << "Overflow" << endl;
            return 0xffffffffffffffff;
        }
        b = __shiftleft128(a,b,shift);
        a <<= shift;
    
    
        uint32_t div;
        uint32_t q0,q1;
        uint64_t t0,t1;
    
        //  1st Reduction
        div = (uint32_t)(c >> 32);
        t0 = b / div;
        if (t0 > 0xffffffff)
            t0 = 0xffffffff;
        q1 = (uint32_t)t0;
        while (1){
            t0 = _umul128(c,(uint64_t)q1 << 32,&t1);
            if (t1 < b || (t1 == b && t0 <= a))
                break;
            q1--;
    //        cout << "correction 0" << endl;
        }
        b -= t1;
        if (t0 > a) b--;
        a -= t0;
    
        if (b > 0xffffffff){
            cout << "Overflow" << endl;
            return 0xffffffffffffffff;
        }
    
        //  2nd reduction
        t0 = ((b << 32) | (a >> 32)) / div;
        if (t0 > 0xffffffff)
            t0 = 0xffffffff;
        q0 = (uint32_t)t0;
    
        while (1){
            t0 = _umul128(c,q0,&t1);
            if (t1 < b || (t1 == b && t0 <= a))
                break;
            q0--;
    //        cout << "correction 1" << endl;
        }
    
    //    //  (a - t0) gives the modulus.
    //    a -= t0;
    
        return ((uint64_t)q1 << 32) | q0;
    }
    

    Note that if you don’t need a perfectly truncated result, you can remove the last loop completely. If you do this, the answer will be no more than 2 larger than the correct quotient.

    Test Cases:

    cout << muldiv2(4984198405165151231,6132198419878046132,9156498145135109843) << endl;
    cout << muldiv2(11540173641653250113, 10150593219136339683, 13592284235543989460) << endl;
    cout << muldiv2(449033535071450778, 3155170653582908051, 4945421831474875872) << endl;
    cout << muldiv2(303601908757, 829267376026, 659820219978) << endl;
    cout << muldiv2(449033535071450778, 829267376026, 659820219978) << endl;
    cout << muldiv2(1234568, 829267376026, 1) << endl;
    cout << muldiv2(6991754535226557229, 7798003721120799096, 4923601287520449332) << endl;
    cout << muldiv2(9223372036854775808, 2147483648, 18446744073709551615) << endl;
    cout << muldiv2(9223372032559808512, 9223372036854775807, 9223372036854775807) << endl;
    cout << muldiv2(9223372032559808512, 9223372036854775807, 12) << endl;
    cout << muldiv2(18446744073709551615, 18446744073709551615, 9223372036854775808) << endl;
    

    Output:

    3337967539561099935
    8618095846487663363
    286482625873293138
    381569328444
    564348969767547451
    1023786965885666768
    11073546515850664288
    1073741824
    9223372032559808512
    Overflow
    18446744073709551615
    Overflow
    18446744073709551615
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

What is the most accurate way to determine the amount of cpu speed and
What is the most effective and accurate way to geocode a UK postcode? Using
I am using an opengl es iphone application. What is the most accurate way
What is the most efficient and accurate way to determine how much data is
Possible Duplicate: What is the most accurate way to retrieve a user's correct IP
I want to divide two ull variables and get the most accurate outcome. what
I'm wondering what the most accurate way of converting a big nanoseconds value is
What would be the best and most accurate way to determine how long it
What's the best / simplest / most accurate way to detect the browser of
What is the most accurate way of timing a thread or a line of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.