久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

  1. <small id='kcEWv'></small><noframes id='kcEWv'>

    <legend id='kcEWv'><style id='kcEWv'><dir id='kcEWv'><q id='kcEWv'></q></dir></style></legend>
  2. <i id='kcEWv'><tr id='kcEWv'><dt id='kcEWv'><q id='kcEWv'><span id='kcEWv'><b id='kcEWv'><form id='kcEWv'><ins id='kcEWv'></ins><ul id='kcEWv'></ul><sub id='kcEWv'></sub></form><legend id='kcEWv'></legend><bdo id='kcEWv'><pre id='kcEWv'><center id='kcEWv'></center></pre></bdo></b><th id='kcEWv'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='kcEWv'><tfoot id='kcEWv'></tfoot><dl id='kcEWv'><fieldset id='kcEWv'></fieldset></dl></div>

      • <bdo id='kcEWv'></bdo><ul id='kcEWv'></ul>
      <tfoot id='kcEWv'></tfoot>

      在 64 位中進行組合乘除運算的最準確方法是什么

      Most accurate way to do a combined multiply-and-divide operation in 64-bit?(在 64 位中進行組合乘除運算的最準確方法是什么?)

      <small id='5BKIj'></small><noframes id='5BKIj'>

          <legend id='5BKIj'><style id='5BKIj'><dir id='5BKIj'><q id='5BKIj'></q></dir></style></legend>
        • <tfoot id='5BKIj'></tfoot>

                <bdo id='5BKIj'></bdo><ul id='5BKIj'></ul>

                  <tbody id='5BKIj'></tbody>
              • <i id='5BKIj'><tr id='5BKIj'><dt id='5BKIj'><q id='5BKIj'><span id='5BKIj'><b id='5BKIj'><form id='5BKIj'><ins id='5BKIj'></ins><ul id='5BKIj'></ul><sub id='5BKIj'></sub></form><legend id='5BKIj'></legend><bdo id='5BKIj'><pre id='5BKIj'><center id='5BKIj'></center></pre></bdo></b><th id='5BKIj'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='5BKIj'><tfoot id='5BKIj'></tfoot><dl id='5BKIj'><fieldset id='5BKIj'></fieldset></dl></div>
                本文介紹了在 64 位中進行組合乘除運算的最準確方法是什么?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                問題描述

                我可以對 64 位整數(shù)進行乘除運算的最準確方法是在 32 位和 64 位程序中(在 Visual C++ 中)嗎?(在溢出的情況下,我需要結果 mod 264.)

                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.)

                (我正在尋找類似 MulDiv64 的東西,除了這個使用內聯(lián)匯編,僅適用于 32 位程序.)

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

                顯然,轉換為 double 并返回是可能的,但我想知道是否有更準確的方法而不是太復雜.(即,我不是在這里尋找任意精度的算術庫!)

                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!)

                推薦答案

                由于這被標記為 Visual C++,我將提供一個濫用 MSVC 特定內在函數(shù)的解決方案.

                這個例子相當復雜.它是 GMP 和 java.math.BigInteger 用于大除法的相同算法的高度簡化版本.

                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.

                雖然我有一個更簡單的算法,但它可能慢了大約 30 倍.

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

                此解決方案具有以下約束/行為:

                • 它需要 x64.它不會在 x86 上編譯.
                • 商不為零.
                • 商在 64 位溢出時飽和.

                請注意,這是針對無符號整數(shù)的情況.圍繞它構建一個包裝器以使其也適用于已簽名的案例是微不足道的.此示例還應生成正確截斷的結果.

                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;
                }
                

                請注意,如果您不需要完美截斷的結果,則可以完全刪除最后一個循環(huán).如果這樣做,答案將不會比正確的商大 2.

                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.

                測試用例:

                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;
                

                輸出:

                3337967539561099935
                8618095846487663363
                286482625873293138
                381569328444
                564348969767547451
                1023786965885666768
                11073546515850664288
                1073741824
                9223372032559808512
                Overflow
                18446744073709551615
                Overflow
                18446744073709551615
                

                這篇關于在 64 位中進行組合乘除運算的最準確方法是什么?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

                【網站聲明】本站部分內容來源于互聯(lián)網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯(lián)系我們刪除處理,感謝您的支持!

                相關文檔推薦

                In what ways do C++ exceptions slow down code when there are no exceptions thown?(當沒有異常時,C++ 異常會以何種方式減慢代碼速度?)
                Why catch an exception as reference-to-const?(為什么要捕獲異常作為對 const 的引用?)
                When and how should I use exception handling?(我應該何時以及如何使用異常處理?)
                Scope of exception object in C++(C++中異常對象的范圍)
                Catching exceptions from a constructor#39;s initializer list(從構造函數(shù)的初始化列表中捕獲異常)
                Difference between C++03 throw() specifier C++11 noexcept(C++03 throw() 說明符 C++11 noexcept 之間的區(qū)別)

                <small id='famYe'></small><noframes id='famYe'>

                  <legend id='famYe'><style id='famYe'><dir id='famYe'><q id='famYe'></q></dir></style></legend>

                    • <bdo id='famYe'></bdo><ul id='famYe'></ul>

                        <tbody id='famYe'></tbody>
                      <i id='famYe'><tr id='famYe'><dt id='famYe'><q id='famYe'><span id='famYe'><b id='famYe'><form id='famYe'><ins id='famYe'></ins><ul id='famYe'></ul><sub id='famYe'></sub></form><legend id='famYe'></legend><bdo id='famYe'><pre id='famYe'><center id='famYe'></center></pre></bdo></b><th id='famYe'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='famYe'><tfoot id='famYe'></tfoot><dl id='famYe'><fieldset id='famYe'></fieldset></dl></div>

                          <tfoot id='famYe'></tfoot>
                        • 主站蜘蛛池模板: 国产一区不卡 | 日韩2020狼一二三 | 久久久国产一区 | 精品久久久久一区 | 欧美日韩高清一区二区三区 | 成人一区二区三区在线观看 | 国产精品无码久久久久 | 中文日韩在线视频 | zzzwww在线看片免费 | 操一草| 欧美一区二区免费电影 | 成人亚洲一区 | 精品久久国产 | 国产精品无码专区在线观看 | 国产成人精品一区二区三区视频 | 久久国内| 日韩成人免费中文字幕 | www成人免费视频 | 黄色视频a级毛片 | 成人欧美一区二区三区黑人孕妇 | 国产精品一区久久久 | 国产成人免费在线观看 | 中文字字幕一区二区三区四区五区 | 日本特黄a级高清免费大片 成年人黄色小视频 | wwww.xxxx免费| 久久青视频 | 精品日韩一区二区三区av动图 | 91一区二区在线观看 | 国偷自产av一区二区三区 | 久久久久久久久久久久一区二区 | 欧美性久久久 | 中文字幕成人免费视频 | 91不卡在线 | 久久99精品久久久 | 一区二区三区不卡视频 | 色综合99 | 国产日韩精品久久 | 欧美成人一区二区三区 | 久草99 | 成人av网站在线观看 | 5060网一级毛片 |