Reputation: 21
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!
Upvotes: 2
Views: 830
Reputation: 811
I change the types to uint64_t
and call it.
#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;
}
It print 4000000000
printf("%" PRIu64...
and #include <inttypes.h>
it for printing uint64_t
Upvotes: 2
Reputation: 51845
Don't assume, just because your operating system or platform is 64-bits, that your C compiler has a 64-bit int
type. In fact, many/most such systems (e.g. MSVC on 64-bit Windows) do not.
If your base int
type is 32-bits, then the sum of two 2000000000
signed integers will overflow (but unsigned should not).
So, declare your numbers
argument as const int64_t numbers[n]
; and, similarly, use that int64_t
type in the declaration of the array in the calling module. You can probably also use long long int
, as this should also be at least 64 bits wide.
You should also change the relevant local int
variables in the sum_two_smallest_numbers
function (and that function's return type) to 'explicit' 64-bit (or long long
) integers.
Upvotes: 1