I was trying to execute this code through gcc compiler:
#include <stdio.h>
int main()
{
unsigned long long int x;
x = 75000 * 75000;
printf ("%llu\n", x);
return 0;
}
But it gave wrong output.
I then tried this:
#include <stdio.h>
int main()
{
unsigned long long int x;
x = (unsigned long long)75000 * (unsigned long long)75000;
printf ("%llu\n", x);
return 0;
}
And it gave correct output !
Why is this so?
The expression 75000 * 75000 is the multiplication of two integer constants. The result of this expression is also an integer and can overflow. The result is then assigned to an unsigned long long, but it has already overflowed so the result is wrong.
To write unsigned long long constants use the ULL suffix.
x = 75000ULL * 75000ULL;
Now the multiplication will not overflow.
Related
how to find the correct type for largest number ?
#include <stdio.h>
/**
* factor_prime - prints the prime factors of a number
* #n: number
*/
void factor_prime(unsigned long long n)
{
long i;
long inter = n;
printf("n : %lld\n", n);
for (i = 2; i <= n; i++)
{
if (n % i == 0)
{
n = n / i;
printf("%ld=%lld*%ld\n", inter, n, i);
return;
}
}
}
int main(void)
{
factor_prime(1718944270642558716715u);
}
output : 3397071787570416427=35568825191561*95507
expected : 1718944270642558716715=343788854128511743343*5
how to fix ?
You are using a too big integer constant that can not be represented in any object of an integer type.
Consider this demonstration program.
#include <stdio.h>
#include <limits.h>
#include <inttypes.h>
int main( void )
{
printf( "%llu\n", ULLONG_MAX );
printf( "%" PRIuMAX "\n", UINTMAX_MAX );
}
Its output is
18446744073709551615
18446744073709551615
The outputted constant contains only 20 digits while your constant 1718944270642558716715u that you are trying to use contains 22 digits.
Pay attention to that in any case your function is incorrect. The function parameter has the type unsigned long long that you are assigning to a variable of the signed type long
void factor_prime(unsigned long long n)
{
long i;
long inter = n;
//...
As you are trying to pass a very big number then the assignment results in getting an invalid value.
The problem with your code is that you're passing a value i.e. 1718944270642558716715u which is out of range for the unsigned long long numeric limit.
You can check the numeric limit of a type using:
For c++
std::numeric_limits<unsigned long long>::max() // 18446744073709551615
For C
#include <stdio.h>
#include <limits.h>
int main(void)
{
printf("%llu", ULONG_LONG_MAX); // 18446744073709551615
}
when you code a function that you want to work for any type of variable try to use the largest variable size. In your case try long long or decimal.
I am trying to convert number stored in the c string to long int. But I am not getting the expected output:
char str[] = "987654321012345";
long int num ;
num = 0;
//num = atol(str);
num = strtol(str, (char **) NULL, 10);
printf("%ld", num);
Output : 821493369
gcc version 4.4.7 20120313 (Red Hat 4.4.7-16)
Can you please advise what am I doing wrong here? Thanks.
In addition to using long long, you can use exact width types from stdint.h. For instance, to guarantee and 64-bit signed number you can use the int64_t type. Regardless what you do, do not cast NULL to char ** and always validate your conversions. E.g.,
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main (void) {
char str[] = "987654321012345";
long num = 0;
errno = 0;
num = strtol (str, NULL, 10);
if (errno) { /* validate strtol conversion */
perror ("strtol conversion failed.");
return 1;
}
printf ("%ld\n", num);
return 0;
}
Example Use/Output
$ ./bin/strtoltst
987654321012345
There are additional error checks you can do on the conversion, but at minimum, make sure errno is not set following your call to strtol or strtoll.
If you would like to use the guaranteed width types, then you can make the following changes:
...
#include <stdint.h>
...
int64_t num = 0;
...
num = strtoll (str, NULL, 10);
The result is the same.
I could reproduce and fix.
Code reproducing the problem
#include <stdio.h>
//#include <stdlib.h>
int main()
{
char str[] = "987654321012345";
long int num ;
char *ix;
num = 0;
//num = atol(str);
num = strtol(str, &ix, 10);
printf("%ld\n", num);
printf("%lu\n", sizeof(long));
return 0;
}
Gives as expected:
821493369
8
After a compilation warning
warning: implicit declaration of strtoll
Reason: as strtoll is undeclared, it is assumed to return an int, so the long value is first truncate to an int and than promoted back to a long.
Fix: just uncomment the #include <stdlib.h> line...
Conclusion: warnings are not meant to be ignored!
You should use long long as datatype for your number.
char str[] = "987654321012345";
long long num = strtoll(str, (char **)NULL, 10);
printf("%lld", num);
According to the C data type:
Long signed integer type. Capable of containing at least the [−2,147,483,647, +2,147,483,647] range; thus, it is at least 32 bits in size.
Long unsigned integer type. Capable of containing at least the [0, 4,294,967,295] range;
Is not enough, so you need a long long or unsigned long long and use %lli or %llu
"987654321012345" is too large.
Strol is outputing long type variable.
Long value is –2,147,483,648 to 2,147,483,647.
try
char str[] = "987654321012345";
char *pEnd;
long long num;
num = 0;
num = strtoull(str,&pEnd, 10);
printf("%lld", num);
return 0;
long long instead of long
strtoull instead of strtol
%lld instead of %ld
The nth term of the series is f(n).
f(n) = 1, when n=1
f(n)= ((n-1)*(8*(n–2)* 2+ 20)+4) , when n>1
P(n)=f(1)+f(2)+.....f(n)
1<=n<=10^9
for a given n we have to find P(n) modulo 10^9+7.
I solved the equation and finally getting the answer as
P(n)=(16n^3-18n^2+14n-12)/3
Problem comes when I implemented it in c++.
Given below the code tell me whats wrong with it and how to resolve it?
#include<stdio.h>
#define c 1000000007
int main()
{
long long int t,n,sum;
scanf("%lld",&t);
while(t--)
{
sum=0;
scanf("%lld",&n);
if(n==1)
printf("1\n");
else
{
sum=(((16*(((((n%c)*(n%c))%c)*(n%c))%c)%c)+14*(n%c))%c-(18*(((n%c)*(n%c))%c)%c+12)%c)/3;
sum++;
printf("%lld\n",sum);
}
}
return 0;
}
There are multiple issues in your code.
Problem 1:
An expression like long long b = ((a%c)*(a%c))%c; with a and b being long long
and c just a "plain number", ie. int, is still subject to int overflow, without
using the full capabilities of long long. The reason is the result of modulo:
long long = ((long long % int) * (long long % int)) % int;
long long = (int * int) % int;
long long = int % int; //overflow here
long long = int;
long long = long long; //expanding too late
//finished
As an example to check (http://ideone.com/kIyM7K):
#include <iostream>
using namespace std;
int main() {
int i = 1000000;
long long ll = 1000000;
cout<< ((999999%i)*(999999%i)*(999999%i)) << endl;
cout<< ((999999%ll)*(999999%ll)*(999999%ll)) << endl;
return 0;
}
In your code, 1000000007 is not a long long ...
Use 1000000007ULL to treat is as unsigned long long
Problem 2:
You´re using (or at least "used", before the edits) %lld in printf and scanf
for unsigned long long, which is %llu. %lld would be a signed long long
Problem 3:
P(n) purely mathematical and without modulo is positive for every natural number n>=1.
But P(0) is negative, and more important: The four parts of your equation modul´t
and the added/subtracted together could result in a negative number, which is congruent
to the positive expected result, but C doesn´t know that.
So, use signed instead of unsigned, and after the whole calculation, check
if the result is <0 and add c to it to make it >0
Problem 4:
A problem with parenthesis and operator precedence somewhere in your long formula.
A working example, but without the loops and input:
#include<stdio.h>
int main()
{
signed long long n, res, c;
n = 2456ULL;
c = 1000000007ULL;
signed long long part1 = (16*(((n%c)*(n%c)%c)*(n%c)%c))%c;
signed long long part2 = (18*((n%c)*(n%c)%c))%c;
signed long long part3 = (14*(n%c))%c;
res = ((part1 - part2 + part3 - 12)%c)/3 + 1;
printf("%lld\n", res);
return 0;
}
Not a problem:
You don´t need a special check for n=1, because the
whole calculation will result in 1 anyways.
I'm getting a size discepancy while using long int in C. The following code:
#include <stdio.h>
void main()
{
printf("%d\n", sizeof(long int));
}
gives 8 as output, so 64 bits are used to represent long int, right? But:
#include <stdio.h>
void main()
{
long int a;
a = 1;
a = a << 32;
printf("%d\n", a);
}
gives 0 (shifting by 31 gives -2147483648, which is -2**31). So, it seems that only 4 bytes are being used. What does this mean? I'm using gcc 4.4.5 with no flags
You're printing it as a normal integer: printf("%d"). Try printing it as a long integer: printf("%ld ...").
why should a code like this should provide a so high result when I give it the number 4293974227 (or higher)
int main (int argc, char *argv[])
{
unsigned long long int i;
unsigned long long int z = atoi(argv[1]);
unsigned long long int tmp1 = z;
unsigned long long int *numbers = malloc (sizeof (unsigned long long int) * 1000);
for (i=0; tmp1<=tmp1+1000; i++, tmp1++) {
numbers[i] = tmp1;
printf("\n%llu - %llu", numbers[i], tmp1);
}
}
Result should start with the provided number but starts like this:
18446744073708558547 - 18446744073708558547
18446744073708558548 - 18446744073708558548
18446744073708558549 - 18446744073708558549
18446744073708558550 - 18446744073708558550
18446744073708558551 - 18446744073708558551
ecc...
What's this crap??
Thanks!
atoi() returns int. If you need larger numbers, try strtol(), strtoll(), or their relatives.
atoi() returns (int), and can't deal with (long long). Try atoll(), or failing that atol() (the former is preferred).
You are printing signed integers as unsigned.