我知道签名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;
}
我的实施有什么问题。
答案 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>