C语言 INT_MIN 的绝对值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22268815/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Absolute value of INT_MIN
提问by Morgan Wilde
How could I extract the absolute value of INT_MINwithout overflowing? See this code for the problem:
我怎样才能在INT_MIN不溢出的情况下提取的绝对值?请参阅此代码以解决问题:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("INT_MAX: %d\n", INT_MAX);
printf("INT_MIN: %d\n", INT_MIN);
printf("abs(INT_MIN): %d\n", abs(INT_MIN));
return 0;
}
Spits out the following
吐出以下内容
INT_MAX: 2147483647
INT_MIN: -2147483648
abs(INT_MIN): -2147483648
I need this for a check if an intvalue is greater than zero.
我需要这个来检查一个int值是否大于零。
As for this question being a duplicate of Why the absolute value of the max negative integer -2147483648 is still -2147483648?, I have to disagree, since this is a HOW, not a WHY question.
至于这个问题是为什么最大负整数的绝对值 -2147483648 仍然是 -2147483648?,我不得不不同意,因为这是一个如何,而不是一个为什么的问题。
采纳答案by ajay
The %dconversion specifier in the format string of printfconverts the corresponding argument to a signed decimal integer, which in this case, overflows for the inttype. C standard specifically mentions that signed integer overflow is undefined behaviour. What you should do is to use %uin the format string. Also, you need to include the headers stdio.hand stdlib.hfor the prototype of the functions printfand absrespectively.
%d格式字符串中的转换说明符printf将相应的参数转换为有符号十进制整数,在这种情况下,该int类型溢出。C 标准特别提到有符号整数溢出是未定义的行为。您应该做的是%u在格式字符串中使用。此外,您还需要包括头stdio.h和stdlib.h用于功能原型printf和abs分别。
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
// This solves the issue of using the standard abs() function
unsigned int absu(int value) {
return (value < 0) ? -((unsigned int)value) : (unsigned int)value;
}
int main(void) {
printf("INT_MAX: %d\n", INT_MAX);
printf("INT_MIN: %d\n", INT_MIN);
printf("absu(INT_MIN): %u\n", absu(INT_MIN));
return 0;
}
This gives the output on my 32-bit machine:
这给出了我的 32 位机器上的输出:
INT_MAX: 2147483647
INT_MIN: -2147483648
absu(INT_MIN): 2147483648
回答by abligh
How about
怎么样
printf ("abs(INT_MIN) = %ld", -((long int) INT_MIN));
Or if your longis not longer than an int:
或者,如果您的long长度不超过int:
printf ("abs(INT_MIN) = %lld", -((long long int) INT_MIN));
Or if you are prepared to accept that abs(INT_MIN)is always INT_MAX + 1:
或者,如果您准备好接受,那abs(INT_MIN)总是INT_MAX + 1:
printf ("abs(INT_MIN) = %u", ((unsigned int) INT_MAX ) + 1 );
回答by ninjalj
There is no portable way to extract the absolute value of the most negative number as an integer. The ISO C standard says (§6.2.6.2?2):
没有可移植的方法将最负数的绝对值提取为整数。ISO C 标准说(§6.2.6.2?2):
Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N ).
作为值位的每个位应与相应无符号类型的对象表示中的同一位具有相同的值(如果有符号类型中有 M 个值位,无符号类型中有 N,则 M ≤ N )。
Notice it uses ≤, not <.
注意它使用 ≤,而不是 <。
Since the sign bit in 2's complement has the value ?(2M), and each value bit has a value that is a power of two between 1and 2M-1, there is no way an unsigned integer on implementations where M=Ncan represent 2N, it can only represent up to 2N-1= 1+2+...+2N-1.
由于 2 的补码中的符号位的值为?(2 M),并且每个值位的值都是1和2 M-1之间的2的幂,因此在M=N 的实现中没有无符号整数可以表示2 N,最多只能表示2 N-1= 1+2+...+2 N-1。
回答by xuefu
In C, only the int version exists for the function int abs(int j). You can use another function labsunder the header stdlib.h. Its prototype: long int labs(long int j);
在 C 中,函数 仅存在 int 版本int abs(int j)。您可以labs在标题下使用另一个功能stdlib.h。它的原型:long int labs(long int j);
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("INT_MAX: %d\n", INT_MAX);
printf("INT_MIN: %d\n", INT_MIN);
printf("abs(INT_MIN): %ld\n", labs((long)INT_MIN));
return 0;
}
回答by xmoex
Casting into the next available greater integer type should do it. but you have to use the correspondant abs-variant (in this case llabs(...))
转换到下一个可用的更大整数类型应该这样做。但你必须使用对应的 abs-variant(在这种情况下llabs(...))
printf("llabs(INT_MIN): %lld\n", llabs((long long int)INT_MIN));
edit:
编辑:
you can check what's the next greater type by comparing INT_MINto LONG_MINand LLONG_MIN. Maybe in your case a cast to longwill already do it.
您可以通过与和进行比较INT_MIN来检查下一个更大的类型是什么。也许在你的情况下,一个演员会已经这样做了。LONG_MINLLONG_MINlong
printf("labs(INT_MIN): %ld\n", labs((long int)INT_MIN));
Note that the explicit casts are in fact unnecessary as the function itself would cast the argument implicitly
请注意,显式转换实际上是不必要的,因为函数本身会隐式转换参数
回答by ThoAppelsin
First things first, you have to #include <math.h>to properly use the absfunction.
首先,您必须#include <math.h>正确使用该abs功能。
Second thing is, if the only thing you want to achieve is to print the absolute value of the INT_MINdefined in limits.h, you can just print it out as an unsigned integeror as a long long integer, like this:
第二件事是,如果您唯一想要实现的是打印INT_MIN定义 in的绝对值limits.h,您可以将其打印为 anunsigned integer或 a long long integer,如下所示:
printf( "abs(INT_MIN): %u\n", abs( INT_MIN ) ); // %u for unsigned int
printf( "abs(INT_MIN): %lld\n", abs( INT_MIN ) ); // %lld for long long int
Since you want to have the absolute value, which most definitely will be unsigned, this should be alright.
既然你想要绝对值,绝对是无符号的,这应该没问题。
If you don't want to include math.h, you can make it on your own like this:
如果你不想包含math.h,你可以像这样自己制作:
// ternary implementation of the function abs
printf( "abs(INT_MIN): %u\n", ( INT_MIN > 0 ) ? INT_MIN : -INT_MIN );
If you want to use it for other purposes, then you can store the abs( INT_MIN )value in unsigned intor long long intvariables.
如果您想将其用于其他目的,则可以将abs( INT_MIN )值存储在unsigned int或long long int变量中。

