c ++如何表示负值

时间:2015-07-13 09:24:36

标签: c++ bit-manipulation

我知道签名int的二进制等价值是11111111111111111111111111111111
基于此,我试图在不使用limits.h头文件的情况下为我的程序创建最大和最小int值。运行我的下面的代码后,我得到最小值为-2147483648,最大值为0.以下是我的代码:

int MaxInt(){
      int MAX = -1;
      MAX = 0 << ((sizeof(int)*8)-1);

     return MAX;
}


int MinInt(){
      int MIN = 0;
      MIN  = 1 << ((sizeof(int)*8)-1);

     return MIN;
}

我的实施有什么问题。

4 个答案:

答案 0 :(得分:2)

在功能

int MaxInt(){
      int MAX = -1;
      MAX = 0 << ((sizeof(int)*8)-1);

     return MAX;
}

您首先将-1分配给MAX,然后覆盖其值。所以这项任务没有意义。

此外,如果向左移0,那么你将再次获得0,取决于你将移动0的时间。:)

为2的补码内部表示获取int类型的对象的最大值的最简单方法是以下

int MaxInt()
{
    int MAX = -1u >> 1;
    return MAX;
}

或者你可以写简单

int MaxInt()
{
    return -1u >> 1;
}

这是一个示范程序

#include <iostream>

constexpr int MaxInt()
{
    return -1u >> 1;
}

constexpr int MinInt()
{
    return ~( -1u >> 1 );
}

int main()
{
    std::cout << MaxInt() << std::endl;
    std::cout << MinInt() << std::endl;
} 

程序输出可能看起来像

2147483647
-2147483648   

答案 1 :(得分:2)

您的实施有几个错误:

首先,您的-1表示假定int具有二进制补码32位表示。 int无法保证这一点。 (适用于std::int32_t。)

其次,您假设int具有sizeof(int)*8位。这根本不能保证。

在所有这些假设下,您的实施仍然存在错误:

0 << ((sizeof(int)*8)-1);

可以写成(在数学上,而不是在c ++中):

0 * 2**((sizeof(int)*8)-1)

现在,如您所知,将某些内容与0相乘会产生0

假设给出了二进制补码,以下简单实现应该有效:

MIN = -1 << ((sizeof(int)*8)-1);
MAX = ~MIN;

答案 2 :(得分:1)

  

我的实施有什么问题

MAX = 0 << ((sizeof(int)*8)-1);

任何数量的零移动将始终为零。

答案 3 :(得分:1)

这不是C ++特有的,而是2的补码形式。在2的补码中,最重要的位并不仅仅表示符号(该值为负),而是表示2的幂(即,对于8位2&#39; s)补数,最重要的位代表-2 ^ 7)。

要设置最负数,只应设置最高位。

  // Disclaimer: this should work for *most* devices, but it
  // is device-specific in that I am assuming 2's complement
  // and I am also assuming that a char is 8-bits. In theory,
  // you might find a custom chip where this isn't true,
  // but any popular chip will probably have this behavior:

  int number_of_digits_in_int = sizeof(int) * 8;
  int most_significant_digit_index = number_of_digits_in_int - 1;
  int most_negative_int = 1 << most_significant_digit_index;

要设置最大正数,应设置所有正位:

  // The complement of 0 has all bits set. This value, by the way
  // is the same as "-1" in 2s complement form, but writing it
  // this way for clarity as to its meaning.
  int all_bits_set = ~(static_cast<int>(0));

  // Using an XOR with the most negative integer clears the
  // most-signficant sign bit, leaving only positive bits.
  int largest_positive_int = all_bits_set ^ most_negative_int;

或者更简单:

  // Since the most negative integer has only the negative bit set,
  // its complement has only the positive bits set.
  int largest_positive_int = ~most_negative_int;

正如其他人所说,你应该只使用std::numeric_limits。这也将使您的代码可移植,甚至可以在不使用2s补充的非常奇特的设备上工作,例如,更不用说您自己编写的代码越少,您所犯的错误就越少。< / p>