0

I'm writing a method to check if a number is palindrome or not. For example 12321 is palindrome and 98765 is not. In my program I've used a recursive function to create exactly opposite of given number, like 56789 for 98765 and then checking if two numbers are equal or not. But I'm not getting exact opposite of 98765 which is 56789 instead I'm getting 56787.

Here's my code-

#include<iostream>
#include<bits/stdc++.h>

using namespace std;

long int oppositeNum(int n){

    if(n<10 && n>=0) return n;
    if(n<0) return 0;

    static int m=0;
    int x = n%10;
    long int num = oppositeNum(n/10);
    cout << num << "\n";
    return (num+ (x*pow(10,++m)));
}

int main(){
    int n = 98765;
    int oppNum = oppositeNum(n);
    cout << oppNum;
    if(oppNum==n){
        cout << "Number is palindrome";
    }else{
        cout << "Number is not palindrome";
    }
    return 0;
}

I'm not getting the exact opposite of my original nnumber. the last digit is getting decremented by 1 every time is what I've observed. Can anyone help?

Prateek Gautam
  • 274
  • 2
  • 5
  • 23
  • the output of `oppositeNum(int n)` is n't as you expect. Why do U use `static`? I suggest to convert your nymber to a string, then apply the normal palindrome function – asmmo Feb 08 '20 at 11:01
  • 1
    You probably should name the function `palindromeNumber` or something like that opposite in mathematic is a number that you get when multiplying the original number by -1. – Piotr Siupa Feb 08 '20 at 11:06
  • 1
    @anonymous The `static` keyword don't hurt in this case, when the function is called only once but I agree that this is a very bad practice. The better approach would be to write a recursive function with two parameters `n` and `m`. Then a [wrapper function](https://en.wikipedia.org/wiki/Recursion_(computer_science)#Wrapper_function) could have ane parameter and the check for negative numbers. – Piotr Siupa Feb 08 '20 at 11:11
  • I ran it https://wandbox.org/permlink/70C4fxHPCyAzGB3v, and it works, maybe the function is not the problem. – anastaciu Feb 08 '20 at 11:53
  • A number cannot be a palindrome. The question here is about the **base-10 representation** of a number. That's text. – Pete Becker Feb 08 '20 at 14:29

4 Answers4

2

I can not reproduce the result you are getting. Maybe it is a consequence of using the function pow

But in any case your function may not be called the second time for a different number because the static variable m is not reinitialized to 0. m continues to keep the value after the previous call of the function for a different number.

You can write the function without using the function pow.

Take into account that a reversed number can be too large to be stored an object of the type long because in some systems the type long has the same width as the type int. So I adjust instead of the type long to use the type long long as the return type.

Here you are.

#include <iostream>

long long int oppositeNum( int n )
{
    static long long int multiplier = 1;

    const int Base = 10;

    int digit = n % Base;

    return ( n /= Base ) == 0 
           ? ( multiplier = 1, digit ) 
           : ( n = oppositeNum( n ) , multiplier *= Base, digit  * multiplier + n );
}

int main() 
{
    int n = 12321;

    std::cout << n << " -> " << oppositeNum( n ) << '\n';

    n = - 12321;

    std::cout << n << " -> " << oppositeNum( n ) << '\n';

    n =  98765;

    std::cout << n << " -> " << oppositeNum( n ) << '\n';

    n = -98765;

    std::cout << n << " -> " << oppositeNum( n ) << '\n';

    return 0;
}

The program output is

12321 -> 12321
-12321 -> -12321
98765 -> 56789
-98765 -> -56789
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2
    return (num + float(x*pow(10,++m)));

just do this and it will work. the ans is wrong cos the pow func is giving out 4999 and 5999 that is why it changes the units place.

IbrahimTG99
  • 149
  • 1
  • 10
1

Try this:

return round(num+ (x*pow(10,++m)));

Sometimes the pow function will return the approximated result. e.g. pow(10, 5) could be 99999.9999999, if you round it, you'll get 100000 else it takes the floor value (I think).

paul-shuvo
  • 1,874
  • 4
  • 33
  • 37
1

I changed only as much as it seemed neccessary. It still could use some tail recursion but this would probably required rewriting the whole algorithm.

long int oppositeNum(int n, int &m){
    if(n<10) return n;

    int x = n%10;
    long int num = oppositeNum(n/10, m);
    cout << num << "\n";
    m *= 10;
    return num + x * (long int)m;
}
long int oppositeNum(int n){
    if(n<0) return 0;
    int m = 1;
    return oppositeNum(n, m);
}

What did I change:

  1. Removed the static modifier from m and instead passing it by reference. This allows to use the function more than one time during the program execution. (Also it would allow to use the function by multiple threads at once but I guess this is not a concern here.)
  2. Removed the floating point function pow and instead just multiplying the variable m by ten each iteration.
  3. Added a wrapper for the recursive function so it still can be called with just one argument. Additionally this allow to check for negative numbers only once.

The main source of problem was the function pow. Because it works on floating point numbers, it may not give exact results. It depends on the compiler and the processor architecture but generally you shouldn't expect it to give an exact result. Rounding it to integer additionally increases the difference.

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
  • This doesn't work https://wandbox.org/permlink/WrmXY763jqvNaVgq – anastaciu Feb 08 '20 at 11:45
  • @anastaciu What doesn't work? This link shows a correct result. – Piotr Siupa Feb 08 '20 at 11:47
  • It produces the exact same result as the OP function https://wandbox.org/permlink/70C4fxHPCyAzGB3v – anastaciu Feb 08 '20 at 11:51
  • @anastaciu OP's function does not produce reliable results because it uses floating point arithmetic. It depends on the compiler and the processor. It may happen that it always gives a correct result on a particular machine. This result is correct. – Piotr Siupa Feb 08 '20 at 11:54
  • Thank you for telling the all the related things to it. I will remember about using pow function from now on, also about the static keyword. – Prateek Gautam Feb 08 '20 at 12:33
  • @NO_NAME This does not work if the number is something like `1234567778`, where reversing it will produce an overflow. – PaulMcKenzie Feb 08 '20 at 13:17
  • @PaulMcKenzie Fixed. There was one missing cast. Just be sure to save the result in `long int` if you're going to test that. The original `main()` has `int`. It may still be a problem on architectures where `sizeof(int) == sizeof(long int)`. That's why I always use `` in my programs. – Piotr Siupa Feb 08 '20 at 15:42