Reputation: 11
#include <stdio.h>
#include <string.h>
int main() {
int start, end, i, sum = 0, temp, x, y, z;
puts("Please enter the starting number: ");
scanf("%d", &start);
temp = start;
x = start; y = start + 1;
puts("Please enter the last number till you want to add: ");
scanf("%d", &end);
for (i = start; i < end; i++) {
z = x + y;
x = z;
y = y + 1;
}
printf("The sum of the numbers starting from %d to %d is %d", temp, end, z);
}
Can anyone find what's wrong with this code?
It is working fine for less numbers but when I assign large numbers like 1 to 1000000, it doesn't work i.e. it returns strange values.
Case 1:
Please enter the starting number:
1
Please enter the last number till you want to add:
100
The sum of the numbers starting from 1 to 100 is 5050
But in this case -
Case 2:
Please enter the starting number:
1
Please enter the last number till you want to add:
1000000
The sum of the numbers starting from 1 to 1000000 is 1784293664
What's wrong in this case? Thanks in advance.
Upvotes: 1
Views: 4320
Reputation:
In the second case, you have used a number that is greater than the allowed range for integer data type(it's from -32768
to 32767
for a 16-bit architecture and from -2,147,483,648
to 2,147,483,647
for a 32-bit architecture.) and that's why it leads to integer overflow issue. To fix this problem, you could use other bigger data types such as long int
or long long int
but I recommend you use their unsigned data types i.e unsigned long int
or unsigned long long int
if you're not going to use negative numbers because the range of unsigned data types begins from 0.
Upvotes: 0
Reputation: 12668
Sorry, but don't you know the following way to compute the sum?
long sum_from_a_to_b(long a, long b)
{
int n;
int acc = 0;
for (n = a; n <= b; n++)
acc += n;
return acc;
}
by the way, there's a better formula, which requires no loop:
#include <assert.h>
/* assumed that a <= b */
long sum_from_a_to_b(long a, long b)
{
assert(a <= b);
return b*(b + 1)/2 - a*(a - 1)/2;
}
Upvotes: 0
Reputation: 144780
The range of type int
is not sufficient to represent the value of the sum for large values of start
and stop
(for example the sum for 0
to 65536
exceeds 2147483647
). The variables x
, y
and z
should be defined with type long long
which is guaranteed to represent values up to 9223372036854775807
(9.22E18) or unsigned long
up to 18446744073709551615
(1.84E19).
Furthermore your algorithm to compute the sum is convoluted, with unnecessary or unused intermediary variables. Simplicity is king!
Here is a modified version:
#include <stdio.h>
#include <string.h>
int main() {
int start, end, i;
long long sum;
puts("Please enter the starting number: ");
if (scanf("%d", &start) != 1)
return 1;
puts("Please enter the last number till you want to add: ");
if (scanf("%d", &end) != 1)
return 1;
sum = 0;
for (i = start; i <= end; i++) {
sum = sum + i;
}
printf("The sum of the numbers from %d to %d is %lld\n", start, end, sum);
return 0;
}
For positive start
and stop
values, there is a direct formula to compute the result. You could replace the for
loop with this expression:
if (start <= stop) {
// take the sum of integers from 0 to stop: stop * (stop + 1) / 2
sum = (long long)stop * (stop + 1) / 2;
// subtract the sum of integers from 0 to start - 1: (start - 1) * start / 2
sum -= (long long)start * (start - 1) / 2;
} else {
sum = 0;
}
which simplifies as:
if (start <= stop) {
sum = ((long long)stop + start)(stop - start + 1) / 2;
} else {
sum = 0;
}
If start
and/or stop
can be negative, the sum can still be computed directly as:
if (start <= stop) {
// take the sum of integers from 0 to stop - start:
sum = (long long)(start - stop) * ((long long)stop - start + 1) / 2;
// add the initial value (stop - start + 1) times
sum += ((long long)stop - start + 1) * start;
} else {
sum = 0;
}
Which simplifies as:
if (start <= stop) {
sum = ((long long)stop + start)((long long)stop - start + 1) / 2;
} else {
sum = 0;
}
Upvotes: 1
Reputation: 153582
Problem in finding sum of consecutive numbers
OP's code repeatedly adds and attempts a sum greater than INT_MAX
leading to incorrect results.
Use a wider type for the computation of the sum such as long long
or intmax_t
.
Performance: Do not use a loop. The sum of integers [0...N] is N*(N+1)/2
Instead:
//for (i = start; i < end; i++) {
// z = x + y;
// x = z;
// y = y + 1;
//}
// Sum 0 to start
long long sum_start = ((long long) start + 1) * start / 2; // or (start + 1LL)*start/2;
// Sum 0 to end
long long sum_end = ((long long) end + 1) * end / 2;
// vvvv specifier change
printf("The sum of the numbers starting from %d to %d is %lld",
temp, end, sum_end - (sum_start - start));
Upvotes: 1
Reputation: 11
For large numbers you must use unsigned long long int
instead of int
. Here int
means integer which is up to 3 or 4 digit numbers but when you enter 5 digit numbers or more digit numbers it gives you strange values.
Upvotes: 1
Reputation: 321
It's a case of data overflow.
For your example of computing from 1 to 1000000, the sum of consecutive numbers from 1 to x is x(x+1)/2, which is 500.000.500.000, a value largely above the range of an int (2.147.483 647).
Consider using long long int, and don't forget that regardless of the byte size of your variable up to a certain value you'll overflow anyway.
Upvotes: 1
Reputation: 854
You are using int
which only have value range -32,768 to 32,767
or -2,147,483,648 to 2,147,483,647
for 2 byte
and 4 byte
respectively.
You should use unsigned long long
for your code which have a value range 0 to 18,446,744,073,709,551,615
.
Upvotes: 1