首页 > 解决方案 > 使用 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 非常大。此外,在这个任务中,我们只有无符号整数,所以 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);
}

非常感谢您的回答。在阅读了您的所有帖子并经过一些思考之后,我找到了解决方案......所以,我使用了有符号整数。因为int声明默认调用有符号整数。然后我将前 4 个变量的声明更改为unsigned int。现在它起作用了!我什至不再需要将返回语句打长。

谢谢大家,尤其是@Adrian Mole!

标签: cinteger-overflow

解决方案


我将类型更改为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, 2000000000, 2000000000};

    printf("%" PRIu64, sum_two_smallest_numbers(SIZE, balance));

    return 0;
}

它打印 4000000000

printf("%" PRIu64...#include <inttypes.h>用于打印uint64_t


推荐阅读