-2

I tried to solve this below program but I don't know how to find perfect square inside the given number. I don't know how to approach this problem. plz help me solve the problem.

Program:-

Write a C program to get a number from user and find the perfect square inside the number and print them in ascending order.

Expeccted Output:-

User  :- 4673681
Result:- 1,4,36,.81

User  :- 1625649
Result:- 1,16,25,49,64,256,625.

I wrote the program like below, here, what I done is? I initialized array with some values and make a value as perfect square and then I sorted as a ascending order finally.But, what I expected is totally different. see the above expected output examples for better understanding.

#include<stdio.h>
int main()
{
    int a[10]={4,6,3,9,7,2,8};
    int i,j,m=8,temp;
   // printf("Enter the elements:");
    //scanf("%d",&m);

    for(i=0;i<m;i++)
    {
        a[i]= a[i]*a[i];
    }
    for(i=0;i<m-1;i++)
    {
        for(j=i+1;j<m;j++)
        {
            if(a[i]>a[j])
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    }
    printf("ascending orders:\n");
    for(i=0;i<m;i++)
    {
        printf("%d\n",a[i]);
    }
}
MK Tharma
  • 31
  • 6

1 Answers1

-1

Interesting little problem, it was easily solved.

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

void findsquares(int num)
{
    for(int x = 1; x*x <= num; ++x)
    {
        int m = pow(10,(int)log10(x*x)+1);
        for(int t = num; t; t /= 10)
        {
            printf((t%m == x*x)? "%d, " : "", x*x);
        }
    }
}


int main(void) {
    int num = 1625649;

    findsquares(num);

    return 0;
}

Output

Success #stdin #stdout 0s 4360KB
1, 4, 9, 16, 25, 49, 64, 256, 625, 
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • This solution appears to be subject to floating point errors, and will probably give incorrect results for some values. Certainly the use of floating point `log10` and `pow` is inappropriate for this problem. – Tom Karzes May 31 '20 at 02:35
  • I disagree, Tom. I challenge you to find an example. – abelenky May 31 '20 at 02:37
  • I don't think you can be certain that `pow(10, n)` for integer `n` will always be an integer, even though mathematically it is. It would be faster, safer, and clearer to use `sprintf(buf, "%d", x*x) + 1`. – Tom Karzes May 31 '20 at 02:51
  • In absolutely no way could that be faster. You clearly have no clue what this code is doing. – abelenky May 31 '20 at 03:13
  • I just did a timing test, using x = 100, calculating the function 10 million times, with the two versions placed in a separate file to avoid auto-inlining. As expected, the `sprintf` version was faster (though not by as much as I had hoped). The floating point version took 25% longer with -O3. – Tom Karzes May 31 '20 at 03:29
  • The problem Tom Karzes is alluding to is not floating-point arithmetic *per se*, but the fact that math library routines are difficult to implement, and some bad implementations will return incorrect answers, so they should not be relied on. Microsoft’s `pow` was notorious for this: [1](https://stackoverflow.com/questions/50794890/bizzare-output-shouldnt-output-be-153-instead-of-152/50797370#50797370), [2](https://stackoverflow.com/questions/51869997/whats-wrong-with-long-why-is-subtracting-1-automatically?noredirect=1). – Eric Postpischil May 31 '20 at 10:36
  • That is technically a fault of the implementation, not the floating-point format or specification, as a correct result for the exponentiation of an integer to a non-negative integer is always representable within a certain range of the floating-point format, so it should be produced. For `log10(x*x)`, an exact result is not generally representable, but I expect it can be shown the code would work as intended for that as long as `log10` produces correctly rounded results and the `double` format has sufficient precision. The latter is cannot be relied upon from the C standard alone. – Eric Postpischil May 31 '20 at 10:39
  • However, there are other problems with the code. One is that it does not find 0, as in 101. Another is due to the problem statement not specifying whether repeated matches should be reported multiple times (should 44 yield 4 and 4 or just 4?). If they should not, this program fails by reporting 1 and 1 for 11. If they should, this program fails by not reporting 1 twice in 201, once for “1” and once for “01”. – Eric Postpischil May 31 '20 at 10:44
  • The code will overflow when `num` exceeds the square of `floor(sqrt(INT_MAX))`. Then `x*x <= num` is not satisfied by any `x` less than or equal to `floor(sqrt(INT_MAX))`, so it is incremented beyond that, and then `x*x` would exceeds `INT_MAX`. E.g., for `num` = 2,147,395,601, 46,340 does not suffice for `x`, so it is incremented to 46,341, whose square is 2,147,488,281, which exceeds the 32-bit `INT_MAX` of 2,147,483,648. – Eric Postpischil May 31 '20 at 10:52
  • Also, the “answer” merely provides code without documentation or explanation, which is generally not a good answer for questions. It does not teach students well and promotes Stack Overflow as a coding or homework-cheating service. – Eric Postpischil May 31 '20 at 11:00