如何解决将unsigned int与unsigned int相加时发生溢出
我正在尝试为此解决方案(codewars cata,6 kyu):
创建一个函数,该函数返回两个最低正数的和 给出至少4个正整数的数组的数字。没有浮球或 非正整数将被传递。例如,当一个数组是 如[19、5、42、2、77]这样传递,输出应为7。 [10,343445353,3453445,3453545353453]应该返回3453455。
我几乎找到了它。但是显然,我对这里的类型力学有些误解。对于测试用例
数字= {2000000000、2000000000、2000000000、2000000000、2000000000}
我得到溢出。这对我来说是完全奇怪的。我读过C int类型的大小取决于编译系统。我有64位系统,所以我的int很大。此外,在此任务中,我们只有 unsigned 个整数,因此看来32位 4 * 10 ^ 9可能就足够了。我尝试使用uint_32t和uint_64t类型。现在,我正在尝试转换所有变量,这不是方便的方法。寻找解决方案我还需要了解什么?
这是我当前的代码:
#include <stddef.h>
#include <stdio.h>
long sum_two_smallest_numbers(size_t n,const int numbers[n]) {
int current_low1;//suppose first 2 ones are the lowest
int current_low2;//and current_low1 is reserved for the lowest one
int delta1;//variables for comparations
int delta2;
//every new value in array to be compared with
//current_low1 and current_low2.
//then define - if new values are lesser
//and if so - find out is new value the lowest
if (numbers[0] < numbers[1]){
current_low1 = numbers[0];
current_low2 = numbers[1];
} else {
current_low1 = numbers[1];
current_low2 = numbers[0];
}
int ind;
for (ind = 2; (unsigned long) ind < n; ind++){
if ((numbers[ind] < current_low1) && (numbers[ind] < current_low2)){
delta1 = current_low1 - numbers[ind];
delta2 = current_low2 - numbers[ind];
if (delta1 > delta2){
current_low1 = numbers[ind];
} else{
current_low2 = numbers[ind];
}
} else if ((numbers[ind] >= current_low1) && (numbers[ind] < current_low2)){
current_low2 = numbers[ind];
} else if ((numbers[ind] < current_low1) && (numbers[ind] >= current_low2)){
current_low1 = numbers[ind];
}
}
return (unsigned long)(current_low1 + current_low2);
}
非常感谢您的回答。在阅读所有帖子并经过深思熟虑后,我找到了解决方案... 因此,我使用了 signed 整数。因为 int 声明默认情况下会调用带符号整数。然后,我将前4个变量的声明更改为 unsigned int 。现在就可以了!我什至不再需要将返回语句打成长串。
谢谢大家,尤其是@Adrian Mole!
解决方法
我将类型更改为uint64_t
并调用它。
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
uint64_t sum_two_smallest_numbers(size_t n,const uint64_t numbers[n]) {
uint64_t current_low1;//suppose first 2 ones are the lowest
uint64_t current_low2;//and current_low1 is reserved for the lowest one
uint64_t delta1;//variables for comparations
uint64_t delta2;
//every new value in array to be compared with
//current_low1 and current_low2.
//then define - if new values are lesser
//and if so - find out is new value the lowest
if (numbers[0] < numbers[1]){
current_low1 = numbers[0];
current_low2 = numbers[1];
} else {
current_low1 = numbers[1];
current_low2 = numbers[0];
}
size_t ind;
for (ind = 2; ind < n; ind++){
if ((numbers[ind] < current_low1) && (numbers[ind] < current_low2)){
delta1 = current_low1 - numbers[ind];
delta2 = current_low2 - numbers[ind];
if (delta1 > delta2){
current_low1 = numbers[ind];
} else{
current_low2 = numbers[ind];
}
} else if ((numbers[ind] >= current_low1) && (numbers[ind] < current_low2)){
current_low2 = numbers[ind];
} else if ((numbers[ind] < current_low1) && (numbers[ind] >= current_low2)){
current_low1 = numbers[ind];
}
}
return (current_low1 + current_low2);
}
#define SIZE 5
int main()
{
uint64_t balance[SIZE] = {2000000000,2000000000,2000000000};
printf("%" PRIu64,sum_two_smallest_numbers(SIZE,balance));
return 0;
}
它打印4000000000
printf("%" PRIu64...
和#include <inttypes.h>
用于打印uint64_t
不要仅仅因为您的操作系统或平台是64位,就假定C编译器具有64位int
类型。实际上,许多/大多数此类系统(例如64位Windows上的MSVC)没有。
如果您的基本int
类型为32位,则两个2000000000
有符号整数 的总和将溢出(但未签名)。
因此,将您的numbers
参数声明为const int64_t numbers[n]
;并且类似地,在调用模块的数组声明中使用int64_t
类型。您可能还可以使用long long int
,因为它也应该至少 64位宽。
您还应该将int
函数(以及该函数的返回类型)中的相关局部sum_two_smallest_numbers
变量更改为“显式”的64位(或long long
)整数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。