C program that checks if a number is palindromic

143 Views Asked by At

I wrote this C program which compiles just great, but when I enter an input it never stops running and when I force stop it, it says "floating point exception (core dumped)". It is basically a function implemented in a bigger program but we dont need that in this case. So whats the deal?

This is the block of code. I wrote the main function just to test the isPal function.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int NumOfDigits(long long x) {
    int sum = 1;
    while (x / 10 != 0) {
        sum ++;
        x = x / 10;
    }
    return sum;
}

int isPal(long long x) {
    int f, c, front, back, sum;
    sum = NumOfDigits(x);
    
    c = pow(10,(sum-2));
    front = x / pow(10,(sum - 1));
    back = x % 10;
    f = 1; 

    while (x != 0 && f == 1) {
        if (front == back) {
           x = (x / 10) % c;
           c /= 100;
           sum -=2;
           front = x / pow(10,sum);
           back = x / 10;
        } else {
           f = 0;
        }
    }
    if (f) {
        return 1;
    } else {
        return 0;
    }
}

int main() {
    int f;
    long long x;
    scanf("%lld\n", &x);
    f = isPal(x);
    if (f) {
        printf("yes"); }
        else { printf("no"); }
}
2

There are 2 best solutions below

0
Eric Postpischil On

If you are testing with a single digit input, then sum is one, and c = pow(10,(sum-2)); sets c to zero, since 10−1 = .1, which becomes zero when converted to int for assignment to c. Then (x / 10) % c divides by zero.

With other numbers with an odd number of digits, c will start non-zero, but c /= 100 will eventually change it to zero, again causing (x / 10) % c to divide by zero.

You need to change the code to avoid this division by zero.

Additionally, some low-quality pow implementations return inaccurate results even when the mathematical result is exactly representable. For example, pow(10, 0) may return a number slightly less than one even though it ought to return one. You can correct for that by using round(pow(10, i)) instead of pow(10, i) (or lround or one of the other rounding functions).

However, when testing whether an input numeral is palindromic, it is often preferable to merely read the numeral as a string and test the characters directly, without converting them to a number.

0
Support Ukraine On

The answer from @EricPostpischil explains the divide-by-zero problems very well. This answer is just to show an alternative approach.

The maximum number of digits in a long long is fairly small so it's not a problem to calculate all the digits and store them in an array. Then the high/low digits are easy to compare.

Something like:

int isPal(long long x) 
{
    int digit[32]; // long long has less than 32 digits
    int cnt = 0;
    while(x != 0)
    {
        digit[cnt] = x % 10;
        ++cnt;
        x = x / 10;
    }
    
    int low = 0;
    int high = cnt - 1;
    while (low < high)
    {
        if (digit[low] != digit[high]) return 0;
        ++low;
        --high;
    }
    return 1;
}