#include <stdio.h>
int main() {
unsigned long int sum = 0LL;
long i;
for (i = 0LL; i < 100000000; i++) {
sum = sum + i;
}
printf("%i", sum);
}
that's all of my code, and I am curious why it prints 887459712 instead of 4999999950000000, and how to fix this
Your sum is declared unsigned long int, which is big enough for your expected result.The problem is not overflow.
The problem is your printf statement is wrong.
You told it to print a "normal" sized int with %i, which only goes up to about 4.2 billion.
You should tell printf to print an unsigned long int, using %llu
It should be:
printf("%llu", sum);
IDEOne Link
Results
Success #stdin #stdout 0s 5376KB
4999999950000000
Related
Trying to learn C I'm toying around a bit with some for loops and sums. I want to compute the sum of the first n natural numbers without using the mathematical formula n(n+1)/2. I have this code for it:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 100;
int sum = 0;
for (int ix = 0; ix <= n; ix++) {
sum = sum + ix;
}
printf("Sum of the first %d natural numbers is %d\n", n, sum);
}
So for n = 100 I get the sum to be 5050, which is correct. I also get correct when I use n = 10000, however if I go for example n = 1000000 then I get the sum = 1784293664 but correct answer should be sum = 500000500000.
Why does my program stop working when n becomes larger and what is that number of the sum being displayed when n = 1000000?
If you want to calculate a sum of natural numbers then instead of the type int use the type unsigned int.
Correspondingly declare the variable sum as having the type unsigned long long int to decrease the risk of overflow.
For example
unsigned int n = 100;
unsigned long long int sum = 0;
for ( unsigned int ix = 1; ix <= n; ix++){
sum = sum + ix;
}
printf("Sum of the first %u natural numbers is %llu\n" , n, sum);
Or you could include the header <inttypes.h> and use the type uintmax_t for the variable sum as it is shown in the demonstrative program below.
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
unsigned int n = 1000000;
uintmax_t sum = 0;
for ( unsigned int ix = 1; ix <= n; ix++){
sum = sum + ix;
}
printf("Sum of the first %u natural numbers is %" PRIuMAX "\n" , n, sum);
return 0;
}
The program output is
Sum of the first 1000000 natural numbers is 500000500000
Pay attention to that there is no need to introduce the auxiliary variable ix. The loop can look simpler as for example
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
unsigned int n = 1000000;
uintmax_t sum = 0;
while ( n ) sum += n--;
printf( "Sum of the first %u natural numbers is %" PRIuMAX "\n" , n, sum );
return 0;
}
You are hitting variable type 'int' limit. Try using long data type to store the sum.
int type is too small to contain numbers so huge, so an arithmetic overflow happens on the way up there. What you observe is called undefined behaviour (UB for short), this is what officially happens in C when signed integers overflow (unsigned ones simply rollover to zero and on).
#include<stdio.h>
int main(){
int i=0, sum=0, n=10;
while(i<=n){
printf("%d\n",i);
sum=sum+i;
i++;
}
printf("%d",sum);
return 0;
}
How to find sum from 1 to 1 million in C? I tried using unsigned long long data type(my code below) but that prints 500,000,000,000. Correct value is 500,000,500,000.
unsigned long long sum = 0;
for(int i=0;i<1000000;i++)
sum += (unsigned long long)i;
printf("%llu",sum);
This should leave you with the correct answer. In your example you were finding the sum of 0 to 999,999. I also removed the needless casting for you.
unsigned long long sum = 0;
for (unsigned long long i = 1; i <= 1000000; i++) sum += i;
printf("%llu", sum);
The efficiency of the naive approach is terrible ! You should use the property that the sum of the integers from 0 to n is n(n+1)/2.
You sum up all numbers from 0 to 999999. Your result is some Kinde of strange.
With this you should get the correct one:
unsigned long long sum=0;
for(unsigned long long i=1;i<=1000000;i++){
sum+=i;
}
I am using 64 bit operating system ,then also i am not able to print 46th fibonacci number correctly which is less than 4 billion.
#include<cs50.h>
#include<stdio.h>
int main(void)
{
unsigned int n=50;
int array[n];
array[0]=0;
array[1]=1;
printf("%i\n",array[0]);
printf("%i\n",array[1]);
for(int i=2;i<n;i++)
{
array[i]=array[i-1]+array[i-2];
printf("%i\n",array[i]);
}
You have to use long long as your data type of the array. because You are going to store out-range numbers of the integer range.(-2,147,483,648 to 2,147,483,647)
And declaration of int i should be before the for loop.
#include<stdio.h>
int main(void)
{
int n=50;
long long array[n];
array[0]=0;
array[1]=1;
printf("%lli\n",array[0]);
printf("%lli\n",array[1]);
int i;
for(i=2;i<n;i++)
{
array[i]=array[i-1]+array[i-2];
printf("%lli\n",array[i]);
}
}
i am not able to print 46th fibonacci number correctly which is less than 4 billion.
You are most probably going out of range of an integer, which is from -4294967296 to 4294967295.
Change int array[n]; to long long array[n];
Also, the printf's should be changed from %i to %lli
Edit : On running the numbers, you get expected value of F(48) as 4807526976 which is out of range of an integer.
Using Rishikesh Raje's counting system (i.e. 1st Fibonacci is 1) where F(48) is 4807526976, then you weren't able to get F(47) 2971215073 because, as #kaylum commented, you used a signed integer array to hold your values which you need to change to unsigned, and well as change your printf statement to print an unsigned. This would allow you to reach the limit of 32 bit arithmetic:
#include <stdio.h>
#define LIMIT (50)
int main(void) {
unsigned int array[LIMIT] = {0, 1};
printf("%u\n", array[0]);
printf("%u\n", array[1]);
for (size_t i = 2; i < LIMIT; i++)
{
array[i] = array[i - 1] + array[i - 2];
printf("%u\n", array[i]);
}
return 0;
}
To get beyond 32 bits, you can switch to long, or long longs as Rishikesh Raje suggests, but work with unsigned variants if you want to reach the maximum result you can with a given number of bits.
Either Use an unsigned integer array or for more higher values use unsigned long long long array but you don't need an array to print fibonacci series you can simply do this:-
void main()
{
unsigned long long i=1, num1=1, num2=0;
printf("1 \n");
for(i; i<100 ; i++)
{
num1=num1+num2;
num2=num1-num2;
printf("%lli \n", num1);
}
getch();
}
long long n, prod, i;
n = 13;
prod = 1;
for (i = 1 ; i <= n ; i++) {
prod *= i;
}
printf("%d\n", prod);
printf("%d\n", sizeof(long long));
returns
$ 1932053504
$ 8
Result is clearly overflowing. But I don't get why this is happening with long long. sizeof(int) returns 4 [bytes] but the product is the same. What am I doing wrong?
You have to use the correct specifier. The "%d" specifier expects an int and you passed a long long int. According to the c standard this will invoke undefined behavior. The observed behavior might be explicable but that doesn't mean it isn't rigorously undefined behavior.
Fix the code like this
printf("%lld\n", prod);
printf("%zu\n", sizeof(long long));
and it should work as intended.
NOTE: enable compilation warnings and you should find out this kind of mistake very quickly.
Result is clearly overflowing.
That's a wrong conclusion. You are getting a truncated result.
When I run:
#include <stdio.h>
int main()
{
long long n, prod, i;
n = 13;
prod = 1;
for (i = 1 ; i <= n ; i++) {
prod *= i;
}
int truncated_value = prod;
printf("%d\n", prod);
printf("%d\n", truncated_value);
}
I get
1932053504
1932053504
The truncation happens due to the use of the %d format specifier.
You can fix that by using the correct format specifier.
printf("%lld\n", prod);
I am having some problems with writing a C program for this question. Maybe am reading the question wrong and doing it the wrong way. Could someone help me with it please? This is they way I'm trying to do it
#include<stdio.h>
void main(void)
{
int j, sum=0;
long int product=1;
for(j=1;j<=30;j=j+2)
{
sum=sum+j;
}
for(j=2;j<=30;j=j+2)
{
product=product*j;
}
printf("\nThe sum of positive odd numbers is: %d", sum);
printf("\nThe product of positive even numbers is: %d", product);
}
The output I am getting is:
The sum of positive odd numbers is: 225
The product of positive even numbers is: -1409286144
I am getting the product part wrong. I have tried using unsigned long int, long long, unsigned long long. Nothing works.
Try using %ld instead of %d in your printf:
printf("\nThe product of positive even numbers is: %ld", product);
Since it's a long int and not an int.
If you use long long int, you'd want %lld. You might need the long long size, given that this is a very very large product. I don't know if your platform's long int is 32 or 64 bit, but you will certainly need a 64 bit number here.
The long long format string can vary depending on your exact platform and compiler, but mostly things have standardized on %lld nowadays. In particular, old Microsoft compilers sometimes used %I64d.
There are no issues as far as the sum of all odd numbers less than 30 is concerned as it's only 225.But the product of all even numbers (or odd numbers for that matter) less than 30 is an enormous number.For that you need a data type with larger capacity.In the following program I have simply used double instead of long int for product and I have used the %e format specifier to display the product in prinf() in a neat way, though you can use %f as well.
#include<stdio.h>
int main(void) //Return type of main() is "int",not "void" as you've used
{
int j, sum=0;
double product=1; //Change type of "product" to "double"
for(j=1;j<=30;j=j+2)
{
sum=sum+j;
}
for(j=2;j<=30;j=j+2)
{
product=product*j;
}
printf("The sum of positive odd numbers is: %d\n", sum);
printf("The product of positive even numbers is: %e",product); //Use %e
}
Output
The sum of positive odd numbers is: 225
The product of positive even numbers is: 4.284987e+16
calculate use unsinged int (32bit)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef unsigned short UInt16;
typedef unsigned UInt32;
typedef struct _unums {
size_t size;
UInt16 *nums;//array
} UNums;
void UNums_init(UNums *num, UInt16 n){
num->nums = malloc(sizeof(UInt16));
num->nums[0] = n;
num->size = 1;
}
void UNums_mul(UNums *num, UInt16 n){
UInt16 carry = 0;
size_t i;
for(i=0;i<num->size;++i){
UInt32 wk = n;
wk = wk * num->nums[i] + carry;
num->nums[i] = wk % 10000;
carry = wk / 10000;
}
if(carry){
num->size += 1;
num->nums = realloc(num->nums, num->size * sizeof(UInt16));
num->nums[i] = carry;
}
}
void UNums_print(UNums *num){
size_t i = num->size;
int w = 0;
do{
--i;
printf("%0*hu", w, num->nums[i]);
if(!w) w = 4;
}while(i!=0);
}
void UNum_drop(UNums *num){
free(num->nums);
num->nums = NULL;
}
int main( void ){
UNums n;
UInt16 i;
assert(sizeof(UInt32) == 4);//32bit
assert(sizeof(UInt16) == 2);//16bit
UNums_init(&n, 1);
for(i=2;i<=30;i+=2)
UNums_mul(&n, i);
UNums_print(&n);//42849873690624000
UNum_drop(&n);
return 0;
}