Question

There's no real need for a solution to this, I just want to know why. Let's take two numbers:

#include <iostream>
using namespace std;

int main()
{
    unsigned long long int a = 17446744073709551615;
    signed long long int b = -30000000003;
    signed int c;
    c = a/b;
    cout << "\n\n\n" << c << endl;
}

Now, lately the answer I've been getting is zero. The size of my long long is 8 bytes, so more than enough to take it with the unsigned label. The C variable should also be big enough to handle the answer. (It should be -581 558 136, according to Google). So...

Edit I'd like to point out that on my machine...

Using numeric_limits a falls well withing the maximum of 18446744073709551615 and b falls within the minimum limits of -9223372036854775808.

Was it helpful?

Solution

You have a number of implicit conversions happening, most of them unnecessary.

unsigned long long int a = 17446744073709551615;

An unsuffixed decimal integer literal is of type int, long int, or long long int; it's never of an unsigned type. That particular value almost certainly exceeds the maximum value of a long long int (263-1). Unless your compiler has a signed integer type wider than 64 bits, that makes your program ill-formed.

Add a ULL suffix to ensure that the literal is of the correct type:

unsigned long long int a = 17446744073709551615ULL;

The value happens to be between 263-1 and 264-1, so it fits in a 64-bit unsigned type but not in a 64-bit signed type.

(Actually just the U would suffice, but it doesn't hurt to be explicit.)

signed long long int b = -30000000003;

This shouldn't be a problem. 30000000003 is of some signed integer type; if your compiler supports long long, which is at least 64 bits wide, there's no overflow. Still, as long as you need a suffix on the value of a, it wouldn't hurt to be explicit:

signed long long int b = -30000000003LL;

Now we have:

signed int c;
c = a/b;

Dividing an unsigned long long by a signed long long causes the signed operand to be converted to unsigned long long. In this case, the value being converted is negative, so it's converted to a large positive value. Converting -30000000003 to unsigned long long yields 18446744043709551613. Dividing 17446744073709551615 by 18446744043709551613 yields zero.

Unless your compiler supports integers wider than 64 bits (most don't), you won't be able to directly divide 17446744073709551615 by -30000000003 and get a mathematically correct answer, since there's no integer type that can represent both values. All arithmetic operators (other than the shift operators) require operands of the same type, with implicit conversions applied as necessary.

In this particular case, you can divide 17446744073709551615ULL by 30000000003ULL and then account for the sign. (Check the language rules for division of negative integers.)

If you really need to do this in general, you can resort to floating-point (which means you'll probably lose some precision) or use some arbitrary width integer arithmetic package like GMP.

OTHER TIPS

b is getting treated as an unsigned number which is larger than a. Hence you are getting the answer as 0.

Try using it as

c = abs(a) / abs (b)
if ((a < 0 && b > 0 ) || (a> 0 && b < 0))
   return -c;
return c;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top