如何测试以下代码?如果我为声明为'unsigned int'的变量赋予有符号整数,会发生什么?

时间:2022-09-28 07:17:18

I want to know the range of numbers which can be used for 'a' and 'b' without getting error.(ie. the output should also give correct value. )

我想知道可以用于'a'和'b'而不会出错的数字范围。(即输出也应该给出正确的值。)

#include <stdio.h>
#include <stdlib.h>

int sum(int * , int *);

int main()
{
unsigned int a= 10;
int b = -30,c;

c=sum(&a,&b);
printf("sum of %d and %d is %d",a,b,c);

return 0;
}

int sum(int *p , int *q)
{
return *p+*q;
};

I gave a signed number to the variable 'a', which is declared as unsigned integer and '-30' for variable 'b'. I got correct output for values of a greater than -2147483618(-2147483617,-2147483616 and so on). But i got positive values for a=-2147483619 onwards. Why is it so? Please help me out.

我给变量'a'赋了一个带符号的数字,它被声明为无符号整数,变量'b'被赋予'-30'。我得到正确的输出值大于-2147483618(-2147483617,-2147483616等)。但是从a = -2147483619起我得到了正值。为什么会这样?请帮帮我。

3 个解决方案

#1


3  

I don't think the internal representation of unsigned and signed integers is defined in the standard. (Especially since even the size of an 'int' can vary.) So your behavior will be undefined. It may be consistent on a particular system, but it may very well not transfer to another system/compiler.

我不认为标准中定义了无符号和有符号整数的内部表示。 (特别是因为即使'int'的大小也可以变化。)所以你的行为将是不确定的。它可能在特定系统上是一致的,但它很可能不会转移到另一个系统/编译器。

#2


0  

As mentioned in the comments, the issue is that you are going over the range of the integer and unsigned integer ranges. This is the reason why you are getting an unexpected result. From this link:

正如评论中所提到的,问题是你要超越整数和无符号整数范围的范围。这就是您获得意外结果的原因。从这个链接:

int 2 bytes: from -32,768 to 32,767
int 4 bytes: from -2,147,483,648 to 2,147,483,647
unsigned int 2 bytes: from 0 to 65,535
unsigned int 4 bytes: from 0 to 4,294,967,295

int 2字节:从-32,768到32,767 int 4字节:从-2,147,483,648到2,147,483,647 unsigned int 2字节:从0到65,535 unsigned int 4字节:从0到4,294,967,295

In your case, when b (or the result of the addition of a and b) has a value lower than -2,147,483,648 or higher than 2,147,483,647, it overflows and it will have an undefined behavior (for example: what you are getting, a positive value for additions of two negative values).

在你的情况下,当b(或a和b的加法结果)的值低于-2,147,483,648或高于2,147,483,647时,它会溢出并且它将具有未定义的行为(例如:你得到的是什么,是积极的增加两个负值的值)。

You can read more about integer overflow and how C handles it on this Wikipedia page.

您可以在此Wikipedia页面上阅读有关整数溢出以及C如何处理它的更多信息。

#3


0  

For int, the only portable solution involves using INT_MIN and INT_MAX as int overflow is undefined behavior. So to find the range of int, print these two.

对于int,唯一的可移植解决方案涉及使用INT_MIN和INT_MAX,因为int溢出是未定义的行为。所以要找到int的范围,打印这两个。

As overflow with unsigned is well define, the maximum unsigned is always:

由于无符号溢出已定义良好,因此最大无符号总是:

unsigned maxu = -1;  // -1 converts to the maximum unsigned
unsigned minu = 0;

So given unsigned_a + int_b --> int_c, something like the following would detect overflow. The 2nd half likely has a problem TBD.

因此,给定unsigned_a + int_b - > int_c,类似下面的内容将检测溢出。下半场可能有TBD问题。

bool SumWithOverflowDetect(unsigned a, int b, int *c) {
  if (b >= 0) {
    if (INT_MAX - b < a) return true;
    *c = a + b;
  } else {
    unsigned sum = a + b; // converts b to unsigned before the addition
    if (sum > a) return true;
    if (sum > INT_MAX) return true;
    *c = sum;
  }
  return false;
}

An easier way to detect overflow uses int2x

检测溢出的更简单方法是使用int2x

bool SumWithOverflowDetect2(unsigned a, int b, int *c) {
  // int2x is some type wider than int/unsigned
  int2x sum = (int2x) a + (int2x) b;
  if (sum < INT_MIN || sum > INT_MAX) return true;
  *c = (int) sum;
  return false;
}

#1


3  

I don't think the internal representation of unsigned and signed integers is defined in the standard. (Especially since even the size of an 'int' can vary.) So your behavior will be undefined. It may be consistent on a particular system, but it may very well not transfer to another system/compiler.

我不认为标准中定义了无符号和有符号整数的内部表示。 (特别是因为即使'int'的大小也可以变化。)所以你的行为将是不确定的。它可能在特定系统上是一致的,但它很可能不会转移到另一个系统/编译器。

#2


0  

As mentioned in the comments, the issue is that you are going over the range of the integer and unsigned integer ranges. This is the reason why you are getting an unexpected result. From this link:

正如评论中所提到的,问题是你要超越整数和无符号整数范围的范围。这就是您获得意外结果的原因。从这个链接:

int 2 bytes: from -32,768 to 32,767
int 4 bytes: from -2,147,483,648 to 2,147,483,647
unsigned int 2 bytes: from 0 to 65,535
unsigned int 4 bytes: from 0 to 4,294,967,295

int 2字节:从-32,768到32,767 int 4字节:从-2,147,483,648到2,147,483,647 unsigned int 2字节:从0到65,535 unsigned int 4字节:从0到4,294,967,295

In your case, when b (or the result of the addition of a and b) has a value lower than -2,147,483,648 or higher than 2,147,483,647, it overflows and it will have an undefined behavior (for example: what you are getting, a positive value for additions of two negative values).

在你的情况下,当b(或a和b的加法结果)的值低于-2,147,483,648或高于2,147,483,647时,它会溢出并且它将具有未定义的行为(例如:你得到的是什么,是积极的增加两个负值的值)。

You can read more about integer overflow and how C handles it on this Wikipedia page.

您可以在此Wikipedia页面上阅读有关整数溢出以及C如何处理它的更多信息。

#3


0  

For int, the only portable solution involves using INT_MIN and INT_MAX as int overflow is undefined behavior. So to find the range of int, print these two.

对于int,唯一的可移植解决方案涉及使用INT_MIN和INT_MAX,因为int溢出是未定义的行为。所以要找到int的范围,打印这两个。

As overflow with unsigned is well define, the maximum unsigned is always:

由于无符号溢出已定义良好,因此最大无符号总是:

unsigned maxu = -1;  // -1 converts to the maximum unsigned
unsigned minu = 0;

So given unsigned_a + int_b --> int_c, something like the following would detect overflow. The 2nd half likely has a problem TBD.

因此,给定unsigned_a + int_b - > int_c,类似下面的内容将检测溢出。下半场可能有TBD问题。

bool SumWithOverflowDetect(unsigned a, int b, int *c) {
  if (b >= 0) {
    if (INT_MAX - b < a) return true;
    *c = a + b;
  } else {
    unsigned sum = a + b; // converts b to unsigned before the addition
    if (sum > a) return true;
    if (sum > INT_MAX) return true;
    *c = sum;
  }
  return false;
}

An easier way to detect overflow uses int2x

检测溢出的更简单方法是使用int2x

bool SumWithOverflowDetect2(unsigned a, int b, int *c) {
  // int2x is some type wider than int/unsigned
  int2x sum = (int2x) a + (int2x) b;
  if (sum < INT_MIN || sum > INT_MAX) return true;
  *c = (int) sum;
  return false;
}