0

for int value 2,015,671 this code outputs 475,739,751

long long cube(int n)
{
return n*n*n;
}

While the correct value should be 8,189,529,329,933,957,120 but using the pow(n, 3) from <math.h> I got the correct result. If it is an overflow of long long type then why does it work for pow ? And it does not reach the MAX of long long data type 9,223,372,036,854,775,807. What is the explanation of this behaviour?

nga1hte
  • 13
  • 2

2 Answers2

6

Converting the result of an expression to a new type happens too late.

If n is an int then n*n*n is an expression involving only ints and produces an int result (some subtle implicit conversions exist for types smaller than int but it is not the main concern here).

If this result overflows, then placing it in a wider integer won't help recover the lost information.
You need to perform this conversion before computing the expression.

long long cube(int n)
{
long long r=n;
return r*r*r;
}

(or change the parameter to long long)

prog-fh
  • 13,492
  • 1
  • 15
  • 30
  • Thank you for clearing that up. Using pow(2015671, 3) I got 8,189,529,329,933,957,120 but using your code above I got 8,189,529,329,933,956,711 there is difference in last 4 digits. Using an online calculator I got the same ans as (r x r x r) which leads me to believe that pow function is not correct or not precise. Is it true? – nga1hte Jul 09 '20 at 12:43
  • @nga1hte `pow()` implies the usage `double`. `double` has 53 significant bits for its fractional part but 8,189,529,329,933,956,711 requires 63 bits (because of sign). Then the result given by `pow()` is truncated which leads to the difference you can observe. – prog-fh Jul 09 '20 at 12:47
  • prog-fh, Unclear about "because of sign". Could your expand on that? "requires 64 bits (because of sign)" might make sense given 63 for the 0x71A7 0D89 1C5B 3667‬ product. – chux - Reinstate Monica Jul 09 '20 at 16:01
  • @chux-ReinstateMonica Yes I realised afterwards that I was thinking at the same time about this specific value and about the max positive value for `long long` (so 63 instead of 64) but they have nothing in common. Unfortunately it was too late to edit the comment and I didn't want to delete it either since it seems useful to the OP (if we ignore my confusion). Sorry about that. – prog-fh Jul 09 '20 at 16:11
1

You have to explicitly cast int to long long int.

long long cube(int n) {
  return (long long int) n*n*n;
}
  • 3
    You should explicitly state that you convert the *first* `n` (not the result). Then `long long × int` gives `long long`, and so on... Or may be add parenthesis to make it explicit because when reading your code it makes think that you are converting the result (which is not the case actually). – prog-fh Jul 09 '20 at 12:50