1

I have tried to print Armstrong number between 100 and 1000; my code with pow() function print all numbers except 153. But when I tried to run the code temp*temp*temp it gives all numbers including 153. How?

#include<iostream>
#include <math.h>
using namespace std;
int main() {
    int lower, upper;
    cout << "enter the lower and upper bound number";
    cin >> lower >> upper;
    cout<< "armstrong number are " << endl;
    for(int num = lower; num <= upper; num++) {
       int sum = 0, num1 =num,temp;
        while(num1 != 0) {
            temp = num1 % 10;
            // sum = sum + temp * temp * temp; [this gives a correct result]
            sum = sum + pow(temp,3);
            num1 = num1 / 10;
        }
        if(num == sum) 
            cout << num << endl;1
    }
    return 0;
}
Mat
  • 202,337
  • 40
  • 393
  • 406
Jayant Sharma
  • 87
  • 1
  • 7
  • Don't put floating-point math like `pow` in the middle of integer calculations unless you like *weird* things happening. – tadman Apr 09 '20 at 14:44
  • 3
    Because [`pow`](https://en.cppreference.com/w/cpp/numeric/math/pow) operates on floating point numbers and [floating point math is broken](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Yksisarvinen Apr 09 '20 at 14:44
  • You don't even need a power of 3 to see possible issues using `pow`. A [power of 2](https://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os) can give issues. – PaulMcKenzie Apr 09 '20 at 15:05
  • 1
    [Why pow(10,5) = 9,999](https://stackoverflow.com/q/9704195/995714), [Why does pow(5,2) become 24?](https://stackoverflow.com/q/22264236/995714), [Why does gcc compiler output pow(10,2) as 99 not 100?](https://stackoverflow.com/q/25474351/995714) – phuclv Apr 09 '20 at 15:15
  • Floating point maths is _not_ broken. Just many people's expectations of it are. – Asteroids With Wings Apr 15 '20 at 12:53

1 Answers1

0

Although it's fashionable to expect pow to return the best possible result, particularly with integral arguments1, neither the C++ standard nor the IEEE754 floating point standard insist on that.

And with a truncation of the double result to an int, your result could be 1 less than expected.

The solution is to write out small powers longhand: temp * temp * temp in your case.

You might get a better result with std::pow from <cmath> as then your compiler will pick an overload more suitable for your calculation.


1In fact I'd consider an implementation of pow that gave an incorrect result for a third power of an integral argument defective.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • I don't think pow() is working unexpectedly as if you put a `cout << pow(temp,3)` just after `sum = sum + pow(temp,3)` you will see expected result i.e 27, 125 and 1 on passing 153 and 153 as argument. But if you put `cout << sum` just after `sum = sum + pow(temp,3)` then unexpected result are shown i.e. 27, 151 and 152 . Instead of 151 there must be 152.... I hope you got my point. – Jayant Sharma Apr 09 '20 at 19:57