0

for the below shown code

#include<stdio.h>
#include<math.h>
int main()
{
    int a,i,n=0;
    int temp=0;
    scanf("%d",&a);
    //for number of digits
    while(temp>=0)
    {
        n++;
        temp = a / pow(10,n);
        if(temp==0)
            break;
    }
    printf("%d\n",n);
    for (i=1;i<=n;i++)
    {
        temp = a % (int)pow(10,i);
        printf("%d\n",temp);
    }
    return 0;
}

the output is (input is 123)

123
3
3
24
123

Image of the output given by gcc

so the question is why 24 is coming instead of 23 ?

please check the image because the output given by online compiler(ideone) is 23. Only the output by gcc has 24

yeshwanth
  • 27
  • 6

2 Answers2

1

I suspect that the pow() is not numerically stable on that platform you're using. You will get 24, if pow(10, 2) returns a double that is little less than 100, e.g. 99.9999999998765, which when cast to (int) would be truncated, resulting in 99, and thus you get 123 % 99 == 24. You could test what is the output of

printf("%.100f\n", pow(10, 2));

If that be the case, and since it seems you're really doing integer math, I'd have another loop variable for multiples of 10:

int tens;

for (i = 1, tens = 10; i < n; i++, tens *= 10) {
    temp = a % tens;
    printf(tens);
}

(Additionally, the initial version of the code had the following problems: the variable int temp; was read uninitialized (and #include <math.h> was missing by mistake). Thus the code had also undefined behaviour.

The C11 standard appendix J2 says that among others, the behaviour of a program is undefined, when:

An lvalue designating an object of automatic storage duration that could have been declared with the register storage class is used in a context that requires the value of the designated object, but the object is uninitialized. (6.3.2.1).


P.S. The while (temp >= 0) condition is needless (and that is a cause for undefined behaviour), except for a complicated way to ensure that a positive integer is entered; as you'd break out anyway at temp == 0, so you could replace it with while (1))

  • Forgot math.h in the question but it wouldn't compile without, and using an un-initialized int wont result in *undefined behavior* . Although it should be initialized if the loop is running, i dont think this is the cause of the problem. – Fantastic Mr Fox Mar 04 '16 at 17:50
  • 2
    @Ben incorrect. Using uninitialized local variable, whose address is not taken, **will** result in undefined behaviour. – Antti Haapala -- Слава Україні Mar 04 '16 at 17:51
  • @Antii I dont think the way ti is used causes undefined behavior: http://stackoverflow.com/a/11965368/1294207, but i am happy to have my mind changed. – Fantastic Mr Fox Mar 04 '16 at 17:54
  • @AnttiHaapala i have added math.h and initialized temp still the same output shown in image in the question – yeshwanth Mar 04 '16 at 17:54
  • Nope, i re-read my own post, i get it. Thanks for the lesson. – Fantastic Mr Fox Mar 04 '16 at 18:01
  • The undefined behavior is that either the variable will initially have a random value which will probably be unequal to zero, causing the loop to be entered, after which the variable receives a value, or the compiler happily skipping any instruction using the uninitialized variable. – Paul Ogilvie Mar 04 '16 at 18:11
  • 1
    @PaulOgilvie in this case "happily skipping" could be the whole while-loop, happily skipping your hard drive out of the window or anything else, since reading uninitialized local variable is always undefined behaviour and compiler is free to do what ever it wants after the fact. "Having initially random value" is very dangerously wrong, as some crypto libs found out. It is sad how much people try to define undefined behaviour. – Ilja Everilä Mar 04 '16 at 18:28
  • For integer values I'd be *very* surprised if `pow(10, 2)` doesn't return an exact representation of 100, since integers in the range +-2^52 or so are directly representable in IEEE double format. – Alnitak Mar 04 '16 at 18:39
  • @Alnitak it'd be because a floating point unit wouldn't usually calculate it as `10^2`, but instead of terms of `e^(2 * ln(10))` or `2^(2 * log2(10))` – Antti Haapala -- Слава Україні Mar 04 '16 at 18:50
1

I see the following errors:

while(temp>=0)

but temp is not initialized.

temp = a / pow(10,n);

but temp is integer and the calculation is double. You loose precision, which is the probable cause of your wrong output.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41