Why is the long long value not printed as I expect in the following code snippet?
#include <stdio.h>
int main()
{
int x = 1363177921;
long long unsigned y = x * 1000000;
printf("y: %llu\n", y); // Why is 1363177921000000 not printed?
return 0;
}
It's not the printing that's at fault. You have integer overflow in:
long long unsigned y = x * 1000000;
Change that to:
long long unsigned y = x * 1000000ull;
Because your x is not a long long, nor is 1000000 - it is only converted to long long AFTER the multiplication.
Make it 1000000ULL, and you'll get what you want.
the problem is that x is int and 1000000 will be long. Now the compiler will multiply them as it was multiplying 2 long and then the result is converted to long long
To solve add an implicit typecasting before x or 100000 or convert x into long long as show below
#include <stdio.h>
int main()
{
int x = 1363177921;
long long unsigned y = (long long )x * 1000000;
printf("y: %llu\n", y); // Why is 1363177921000000 not printed?
return 0;
}
http://codepad.org/rLW8fGTA
Related
I've written a code:
int a = 1000000000, b = 1000000000;
long long int ans = a * b;
cout << ans << '\n';
this code is causing overflow. I understand that a * b is causing the problem but I have taken long long int variable to keep a*b.
But look at the following code:
int a = 1000000000, b = 1000000000;
long long int ans = (long long int)a * b;
cout << ans << '\n';
it's working fine causing no overflow. Does it make any temporary variable to hold the value when calculating? Please explain the reason behind this strange overflowing.
This makes two temporary variables, (long long int)a and (long long int)b. The second conversion is implicit.
Actual compilers might not bother, if the hardware has a 32*32->64 multiply, but officially the conversions have to occur. On 64 bits hardware, it's essentially free when you load an int in a 64 bit register.
Why when you do this:
int a = 1000000 , b = 1000000;
long long product = a * b;
cout<<product;
It gives some random trash value?Why do both a and b need to be long long in order to calculate it?
You are observing the effects of undefined behavior. This:
a * b
is an (arithmetic) expression of type int, as both operands a and b are of type int. Trying to store the value of 1000000000000 into an int results in the so-called signed integer overflow which is undefined behavior.
Either cast one of the operands to long long, thus causing the entire expression to become long long, which is sufficiently large to accept the value of 1000000000000:
#include <iostream>
int main()
{
int a = 1000000, b = 1000000;
auto product = static_cast<long long>(a) * b;
std::cout << product;
}
Or define one of the operands as long long:
#include <iostream>
int main()
{
long long a = 1000000;
int b = 1000000;
auto product = a * b;
std::cout << product;
}
Optionally, use unsigned long instead.
This will work fine. When you do multiplication of int and int if it gets out of limit then to put it in a long long variable you multiply the result with 1ll or 1LL. When you multiply the result with 1ll the result is converted to long long during calculation of product itself.
int a = 1000000 , b = 1000000;
long long product = 1ll * a * b;
cout << product;
It might not be like other asked questions in stackoverflow. In this problem, it works fine, but in one case, it returns wrong answer. I'm trying to solve the logical issue of this program.
I wrote a program to calculate the sum of this:
x, n, a would be entered by the user:
Here is my program:
#include <iostream>
long long int unsigned fact (long long unsigned int a);
long long int unsigned comb (long long unsigned int n, long long unsigned int r);
long long unsigned intpower (long long unsigned int a, long long unsigned int n);
using namespace std;
int main()
{
int n;
long long unsigned int x, a;
cin >> a >> x >> n;
long long unsigned int sum = 0;
for (int i = 0; i <= n; i++) {
sum += comb(n, i)*intpower(x, i)*intpower(a, (n-i));
}
cout << sum;
return 0;
}
// Calculates Factorial
long long int unsigned fact (long long unsigned int a) {
long long int unsigned p = 1;
for (long long unsigned int i = 1; i <= a; i++) {
p *= i;
}
return p;
}
// Calculates the combination
long long int unsigned comb (long long unsigned int n, long long unsigned int r) {
return (fact(n)/fact(r)/fact(n-r));
}
long long unsigned intpower (long long unsigned int a, long long unsigned int n){
long long unsigned int p = 1;
for (long long unsigned int i = 1; i <=n ; i++){
p *= a;
}
return p;
}
But in one case, my program returns wrong answer. Here's the test done my a website that verifies the written programs for problems:
Do you guys have any idea why I got wrong answer in one test? The thing is I don't know what numbers would be entered in test 1, but there should be a logical issue that it gives wrong answer in one case.
Kind regards.
As the comments have pointed, the failing test case is most probably because of a corner-side with the maximum values of the inputs. The range that you can store in a long long int data type (if your compiler support the type) is from -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807. It means that if in your case you have x, a and n as their maximum values, you will have an overflow. For an example, the output of your code with the following inputs is the same:
for:
int n = 10;
long long unsigned int x = 9999999999;
long long unsigned int a = 1000000000;
output is: 9223372036854775808
int n = 10;
long long unsigned int x = 1000000000;
long long unsigned int a = 1000000000;
the output is again: 9223372036854775808
Here is the code to calculate nCr % P by using Fermat's little theorem
long long power(long long x, long long y, long long p)
{
long long res = 1; // Initialize result
x = x % p; // Update x if it is more than or
// equal to p
while (y > 0)
{
// If y is odd, multiply x with result
if (y & 1)
res = (res*x) % p;
// y must be even now
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
// Returns n^(-1) mod p
long long modInverse(long long n, long long p)
{
return power(n, p-2, p);
}
// Returns nCr % p using Fermat's little
// theorem.
long long nCrModPFermat(long long n, long long r, long long p)
{
// Base case
if (r==0)
return 1;
// Fill factorial array so that we
// can find all factorial of r, n
// and n-r
long long fac[n+1];
fac[0] = 1;
for (long long i=1 ; i<=n; i++)
fac[i] = fac[i-1]*i%p;
return (fac[n]* modInverse(fac[r], p) % p *
modInverse(fac[n-r], p) % p) % p;
}
To optimise the code, I precalculated the fac[] array and passed it as an argument in the nCrModPFermat() function:
long long nCrModPFermat(long long n, long long r, long long p,long long fac[])
{
//same code as above
}
int main()
{
long long fac[2001];
fac[0] = 1;
for (long long i=1 ; i<=2000; i++) //calculating factorials upto 2000
fac[i] = fac[i-1]*i%M;
for(i=0;i<2000;i++)
nCrModPFermat(2000,i,M,fac);
}
My outputs where not as expected. Strangely, when I declared the fac[] array globally and calculated the factorials upto 2000 by calling a function:
long long fac[2001];
void funci()
{
fac[0] = 1;
for (long long i=1 ; i<=2000; i++) //calculating factorials upto 2000
fac[i] = fac[i-1]*i%M;
}
long long nCrModPFermat(long long n, long long r, long long p)
{
//same code as above
}
int main()
{
funci();
for(i=0;i<2000;i++)
nCrModPFermat(5000,i,M);
}
I got the expected outputs.
I just want to know why passing the array caused an error in the code
I'm trying to understand why this programm after 2^20-1 value goes in overflow. All my variables are declared unsigned long long, but when I enter 1048756 which is 2^20 it goes in overflow , instead of converting it in a binary number. I thought that the range of u-l-l was 2^64-1.
I included the limits.h library and the maximum value was 8 bytes.This is the code :
#include <stdio.h>
int main(){
unsigned long long n = 100000000;
printf("%llu \n",decimal_binary(n));
return 0;
}
unsigned long long decimal_binary(unsigned long long n)
{
unsigned long long rem, i=1, binary=0;
while (n!=0)
{
rem=n%2;
n/=2;
binary+=rem*i;
i*=10;
}
return binary;
}
And the output is :
14184298036271661312 (Which is not a binary number obviously)
18446744073709551615 // 2^64-1
100000000000000000000 // 2^20 in your funny "decimal binary"
See the problem now?
By the way, if you want to get platform dependence out of this, use uint64_t from stdint.h instead of unsigned long long.
It seems like what you really want is to output a number in binary format. You can't put the conversion back into an integer type like that. You need to construct a string:
void decimal_binary(unsigned long long n, char str[])
{
unsigned long long rem, len=0, temp, i;
while (n!=0)
{
rem=n%2;
n/=2;
// put the binary digit into the string
str[len++] = rem ? '1' : '0';
}
str[len] = '\x0';
// the digits were inserted in reverse order, so reverse the string.
for (i=0;i<=len/2;i++) {
temp = str[i];
str[i] = str[len-1-i];
str[len-1-i] = temp;
}
}
int main(void){
char buff[200];
unsigned long long n = 100000000;
decimal_binary(n,buff);
printf("%s \n",buff);
return 0;
}
Output:
101111101011110000100000000
Let your code detect about when math is getting too big.
#include <stdio.h>
#include <limits.h>
unsigned long long decimal_binary(unsigned long long n)
{
unsigned long long rem, i=1, binary=0, n0;
n0 = n;
while (n!=0)
{
rem=n%2;
n/=2;
binary+=rem*i;
if (i > ULLONG_MAX/10) {
printf("OF %llu %llu\n", n0 , i);
return 0;
}
i*=10;
}
return binary;
}
int main(){
unsigned long long n = 100000000;
printf("%llu %llu\n",n,decimal_binary(n));
n = 100000;
printf("%llu %llu\n",n, decimal_binary(n));
return 0;
}
Output
OF 100000000 10000000000000000000
100000000 0
100000 11000011010100000
main()
{
unsigned long long n = 100000000;
int i;
for(i=sizeof(unsigned long long int)*8-1;i>=0;printf("%llu",n>>i--&1));`
}
OUTPUT::00000000 00000000 00000000 00000000 00000101 11110101 11100001 00000000