按位乘法和除法不适用于大数

时间:2016-02-03 17:37:17

标签: c bit-manipulation

我试图让这个问题起作用,我必须将3/8位乘以然后向零舍入。

到目前为止,我有这个

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

它背后的想法是第一部分取x并将其左移1并添加x以得到乘以3的效果然后向右移3以得到除以8的部分。然后,如果它是负的,我会加1,通过测试看符号位是1(1&amp; 1 = 1)还是0(0&amp; 1 = 0)。我的代码虽然不起作用,但测试结束了。

任何想法我做错了什么?

2 个答案:

答案 0 :(得分:0)

您实际使用的左移将单个位移位为无符号整数,以便最终丢失符号位。这不是你想要的。尝试乘法,看看你应该对比特移动得到什么,看看你得到了什么。

x *= 3.0/8.0;

请注意下面的手动输入,表明如果符号位受影响,结果未定义

Left shift

  

左移运算符使shift-expression中的位成为   向左移动了指定的位置数   添加剂的表达。已经腾出的比特位置   换班操作是零填充的。左移是一个逻辑转变(   从末端移位的位被丢弃,包括符号   位)。有关按位移位类型的更多信息,请参阅   按位改变。

     

以下示例显示了使用unsigned的左移操作   数字。该示例显示了比特发生的情况   将值表示为bitset。有关更多信息,请参阅bitset   类。

     

如果左移有符号数字以使符号位受影响,则结果未定义。以下示例显示了发生的情况   Visual C ++,当1位左移到符号位位置时。

#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 :(得分:0)

您通过使用最负数进行测试然后尝试将其乘以更大(即更负)的数字来溢出您的格式。

有多种方法可以解决这个问题。

  1. 使用更大的内容,如int64。
  2. 使用第二个值来保持溢出。
  3. 将值拆分为一半,然后将其计算为多项式。
  4. 对于一个测试用例,你可以先划分然后再乘法,然后它会工作&#34;但是对于所有你丢失了右边位的情况都会失败。