簡體   English   中英

按位乘法和除法不適用於大數

[英]Bitwise multiplication and division not working with large numbers

我試圖解決這個問題,我必須將3/8乘以位,然后四舍五入為零。

到目前為止,我有這個

((((x<<1)+x)>>3)+((x>>31)&1));

其背后的想法是,第一部分取x並將其向左移動1,再加上x以得到乘以3的效果,然后向右移3以得到除以8的部分。 然后,如果要測試符號位是1(1&1 = 1)還是0(0&1 = 0),則如果它為負數,我將加1。 我的代碼無法正常工作,測試已關閉。

有什么想法我做錯了嗎?

實際上使用的左移會將單個位作為無符號整數進行移位,這樣您最終可能會丟失符號位。 聽起來並不是您想要的。 嘗試乘法,以了解您在逆轉時應該得到什么,以了解您正在得到什么。

x *= 3.0/8.0;

請注意下面的手動輸入,其中顯示如果有符號位受到影響,則結果不確定

左移

左移運算符使移位表達式中的位向左移位加法表達式指定的位置數。 通過移位操作騰出的位位置為零填充。 左移是邏輯移位(從末端移出的位將被丟棄,包括符號位)。 有關按位移位的種類的更多信息,請參見按位移位。

以下示例顯示了使用無符號數字的左移操作。 該示例通過將值表示為位集來顯示這些位所發生的情況。 有關更多信息,請參見bitset類。

如果左移有符號數以使符號位受影響,則結果是undefined 下面的示例顯示將1位左移到符號位位置時在Visual C ++中發生的情況。

#include <iostream>
#include <bitset>
using namespace std;

int main() {
  short short1 = 16384;    
  bitset<16> bitset1{short2};
  cout << bitset1 << endl;  // 0100000000000000 

  short short3 = short1 << 1;
  bitset<16> bitset3{short3};  // 16384 left-shifted by 1 = -32768
  cout << bitset3 << endl;  // 100000000000000

  short short4 = short1 << 14;
  bitset<16> bitset4{short4};  // 4 left-shifted by 14 = 0
  cout << bitset4 << endl;  // 000000000000000  
}

通過使用最大的負數進行測試,然后嘗試將其乘以一個更大的(即,甚至更大的負數)數字,您的格式就顯得很多余。

有多種解決方法。

  1. 使用更大的內容,例如int64。
  2. 使用第二個值來保持溢出。
  3. 將值分成兩半,然后將其計算為多項式。

對於一個測試用例,您可以先除以然后乘以,這將“起作用”,但是在所有情況下,您都會在右側丟失一些位而失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM