I am trying to find a solution for this one (codewars cata, 6 kyu):
Create a function that returns the sum of the two lowest positive numbers given an array of minimum 4 positive integers. No floats or non-positive integers will be passed. For example, when an array is passed like [19, 5, 42, 2, 77], the output should be 7. [10, 343445353, 3453445, 3453545353453] should return 3453455.
And i've almost found it. But obviously i have some misunderstanding about types mechanics here. For the test case
numbers = {2000000000, 2000000000, 2000000000, 2000000000, 2000000000}
I obtain overflow. And this is totally strange for me. I've read that in C int type size depends on compiling system. I have 64bit system, so my int is very large. Moreover, in this task we have only unsigned integers, so it seems that 32 bits <-> 4*10^9 could be enough. I've tried to use uint_32t and uint_64t types. Right now i am trying to cast all variables i have and this is not handy way. What else i need to understand to find the solution?
Here is my current code:
#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);
}
Many thanks for your answers. I've found the solution after reading all your posts and after some pondering... So, i've used signed integers. Because the int declaration invoke signed integer by default. Then i've changed the first 4 variable's declarations to unsigned int. And now it works! I do not even need anymore to typacast the return sentence to long.
Thanks to you all, especially @Adrian Mole!
long longfor the function type and cast the values before adding. If yourlongis 64-bits you still need to cast before addition to prevent overflow.return (long)current_low1 + current_low2;. Your cast is done after the sum has already overflowed.intis guaranteed to be at least 16 bits, but it's NOT guaranteed to be bigger under any circumstances.sizeof(int)to be sure. If yourintis 64-bits, why does the function need to uselong?int, long, unsigned longwithunsigned long long. Replaceint ind;withsize_t ind;intfeels with 2000000000 + 2000000000, overwhelmed 😉