我尝试使用tilde获取int的MAX值。但是输出不是我预期的。 当我运行时:
#include <stdio.h>
#include <limits.h>
int main(){
int a=0;
a=~a;
printf("\nMax value: %d",-a);
printf("\nMax value: %d",INT_MAX);
return 0;
}
我得到输出:
最大值:1
最大值:2147483647
我想,(例如)如果我在RAM中有 0000 (我知道第一位显示的是数字pozitiv或negativ)。之后〜 0000 =&gt; 1111 之后 - ( 1111 )=&gt; 0111 ,我会得到MAX值。
答案 0 :(得分:9)
你有一个32位二进制补码系统。所以 - a = 0
很简单。 ~a
是0xffffffff
。在32位二进制补码表示中,0xffffffff
为-1
。基本代数解释-(-1)
是1
,因此这是您的第一个打印输出来源。 INT_MAX
为0x7fffffff
。
您的逻辑错误在此声明中:“ - ( 1111 )=&gt; 0111 ”,这是不正确。二进制补码的算术否定运算相当于~x+1
- 例如:
~x + 1 = ~(0xffffffff) + 1
= 0x00000000 + 1
= 0x00000001
答案 1 :(得分:3)
是否有理由不能使用std::numeric_limits<int>::max()
?制造简单的错误要容易得多,也不可能。
在你的情况下,假设32位int:
int a = 0; // a = 0
a = ~a; // a = 0xffffffff = -1 in any twos-comp system
a = -a; // a = 1
因此,数学是一种不正确的计算机方式。我无法看到计算最大值的公式化方法:只需使用numeric_limits
(或INT_MAX
,如果您处于纯C代码库中。)
答案 2 :(得分:1)
使用'〜'获取最大值的技巧适用于无符号整数。正如其他人所指出的,它不适用于签名整数。
您的帖子显示的int
相当于signed int
。尝试将类型更改为unsigned int
,看看会发生什么。
答案 3 :(得分:1)
有无公式来计算C中有符号整数类型的最大值。您只需使用来自INT_MAX
和{{limits.h
等的宏。 1}}。
答案 4 :(得分:0)
二进制1...1111
始终代表-1
。简单的数学说-1 * -1 = 1
!
永远记住只有一个零:0...0000
。如果您现在交换MSB并且您是对的,那么您将10...0000
,然后-0
这不是真的(在数学中为0 = -0
,但你的二进制数字会有所不同。)
获取数字的负值不仅仅是交换MSB。
答案 5 :(得分:0)
它不像指示符号的顶部位那么简单。如果是,你可以同时拥有+0和-0。你应该阅读两个补充。
正确的答案是
max = (~0) >> 1;
我不是C / C ++专家,因此您可能需要>>>
。您需要不执行符号扩展的移位运算符。
答案 6 :(得分:0)
2的补码表示法111111 ...是-1;现在,一元减号运算符不会简单地改变符号位(否则它会在每个正常上下文中提供奇怪的结果),但是正确计算数字的相反值,即+1。
如果要更改MSB,可以使用按位运算符将其简单地设置为零。请注意,这种找到int
类型的最大值的方法是不可移植的,因为您正在假设标准不需要表示数字。