繁体   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