-2

I have a simple program which gives the wrong output, the expected output is the digits of the number.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>


using namespace std;

int main()
{
   int n = 125521;
   int d = floor(log10(n));
   printf("%d Digits\n",d+1);
   int t =0;
   while(floor(log10(n))-t)
   { printf("%d-----%d\n",(n/(int)pow(10,floor(log10(n))-t)%10),t); t++;}
   return 0;
}

This gives the output

6 Digits
1-----0
2-----1
5-----2
7-----3
2-----4

Strange output. Why does 7 come ?

I know how to get the digits by other ways but I want this solution to work.

Now as suggested in the answers I get rid of the bug in the while loop (>=0) and I get the output:

enter image description here

adrian008
  • 395
  • 6
  • 18
  • 1
    [check this](http://ideone.com/Dw8a22) its your output. – Sourav Kanta Jun 27 '15 at 06:29
  • @SouravKanta Why do I get wrong output in my CodeBlocks MingW ? This is very bad error. – adrian008 Jun 27 '15 at 06:35
  • I have no idea.Pls wait someone who is better at c will tell you.Ideone gives you right output. – Sourav Kanta Jun 27 '15 at 06:44
  • 1
    Do you like reading code that scrunched up? It is really hard to read. – Jonathan Leffler Jun 27 '15 at 07:00
  • 5
    Don't use `pow`, `log10`, or floating point for this — it's not exact. You need only `/` and `%`. – molbdnilo Jun 27 '15 at 07:01
  • 1
    Cannot reproduce: I get 1, 2, 5, 5, 2 in the first column of digits. I'm using GCC 5.1.0 on Mac OS X 10.10.3, compiling in 64-bit mode. What are you using to get the 7? – Jonathan Leffler Jun 27 '15 at 07:06
  • what are the reasons you want to use the super slow log and pow instead of simple division? – phuclv Jun 27 '15 at 07:11
  • 1
    @adrian008 There is no guarantee that `pow(10, whatever)` will give you an exact answer. http://stackoverflow.com/questions/25678481/why-pown-2-return-24-when-n-5 – PaulMcKenzie Jun 27 '15 at 07:11
  • @molbdnilo yes I know that, using / and % its easier also. But I wanted this way to see one more way. – adrian008 Jun 27 '15 at 07:14
  • @JonathanLeffler I am using GCC 4.8.1 – adrian008 Jun 27 '15 at 07:14
  • On which O/S? What hardware? Again, on my Mac, using GCC 4.8.1 in 64-bit compilation mode (Intel CPU, Mac/BSD maths library), I get the expected 1,2,5,5,2 as the output. Also when compiled in 32-bit mode. – Jonathan Leffler Jun 27 '15 at 07:17
  • Maybe you should print more information to debug what's going on. Print various intermediate expressions to see if you can spot where the 7 comes from. As I noted, I can't reproduce it on my machine. It seems improbable that it was produced, but if you've got the evidence it happened, there must be an explanation. You aren't using a Pentium 4 chip, are you? – Jonathan Leffler Jun 27 '15 at 07:23
  • @JonathanLeffler The link I pointed out shows a question where `pow` can have issues. – PaulMcKenzie Jun 27 '15 at 07:28
  • @PaulMcKenzie: Off-by-one is not wholly implausible (a little unlikely, but not implausible). Off-by-two is rather less likely. I'm curious to know which platform is showing such bad behaviour on arithmetic in the relatively ordinary range of numbers (there's nothing extraordinary about values in the range of 6-digit numbers, unless someone is forcing `float` (32-bit floating point) calculations on the code somehow). – Jonathan Leffler Jun 27 '15 at 07:38
  • 1
    Have you tried finding out which of the many chained expressions there is giving a faulty result? Taking the thing apart for analysis is the first thing that a programmer would do. Also, it makes the code more readable; As it stands, from the mere presentation it wouldn't pass any code review. – Ulrich Eckhardt Jun 27 '15 at 07:41
  • Silly question time: have you printed `n` in your code? What happens when you do? – Jonathan Leffler Jun 27 '15 at 07:49
  • @JonathanLeffler yes it is printing fine. – adrian008 Jun 27 '15 at 08:48

3 Answers3

1

Put proper spaces (n/(int)pow(10,floor(log10(n))-t)%10) in this line.

So many redundant call of floor(log10(n)).

while loop will loop less than 1 from digit numbers.

I have no idea, why you print t besides digits, say:

1-----0
2-----1
     ^^^

Can't reproduce what you said.

Are you looking for this:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>

using namespace std;

int main() {
    int n = 550052111;
    int d = floor(log10(n));
    printf("%d Digits\n", d + 1);
    int t = 0;
    int power, divition, mod;
    int digitCount[10] = {0};
    while (d +1 - t) {
        power = (int) pow(10, d - t);
        divition = n / power;
        mod = divition % 10;
        digitCount[mod]++;
        t++;
    }

    for (t= 0; t < 10; t++) {
        if(digitCount[t]) {
            printf("%d-----%d\n", t, digitCount[t]);
        }
    }
    return 0;
}

Output:

9 Digits
0-----2
1-----3
2-----1
5-----3

Caution: input n must not overflow Integer. To find the digit counts in a number, you do not need floor, pow or log10, only / and % is sufficient.

mazhar islam
  • 5,561
  • 3
  • 20
  • 41
  • I know the solution, i wanted to solve by the method i used. – adrian008 Jun 27 '15 at 07:16
  • @adrian008, which method? Look, in the `printf` function what you do, I do the same buy using different variable to see whether they produce right values or not. Say `1/0 ` can crash your program. – mazhar islam Jun 27 '15 at 07:17
  • @JonathanLeffler, mistake, just copied and paste, that's why `t` came by, typo. – mazhar islam Jun 27 '15 at 07:46
1

There is a bug in your while loop.

while(floor(log10(n))-t)

Should be

while(0 <= floor(log10(n))-t)

The index in your case should start from 0 rather than 1.

Fix that bug and you should get the proper output as follows:

6 Digits
1-----0
2-----1
5-----2
5-----3
2-----4
1-----5
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
artm
  • 17,291
  • 6
  • 38
  • 54
  • 2
    You could also write `while (t <= floor(log10(n)))` which would be clearer still, and `while (t <= d)` to be simpler. This does not explain why the OP sees a 7 instead of the second 5, though. It does explain why they don't see the final 1, but that isn't officially part of the question. – Jonathan Leffler Jun 27 '15 at 07:35
  • Yeah, **while ( t <= d)** is a lot cleaner. – artm Jun 27 '15 at 07:42
1

To find out why you are getting the 7 instead of the 5, you need to do some serious diagnostic printing — maybe using code something like this:

#include <cstdio>
#include <cmath>

using namespace std;

int main()
{
    int n = 125521;
    int d = floor(log10(n));
    printf("n = %d: %d Digits\n", n, d + 1);
    int t = 0;
    while (floor(log10(n)) >= t)
    {
        printf("t = %d: n = %d; L = log10(n) = %f; F = floor(L) = %f\n",
                t, n, log10(n), floor(log10(n)));
        printf("       T = F-t = %f;", floor(log10(n)) - t);
        printf(" P = pow(10,T)= %f\n", pow(10, floor(log10(n)) - t));
        printf("       I = (int)P = %d; D = n/I = %d; M = D %% 10 = %d\n",
               (int)pow(10, floor(log10(n)) - t),
               n / (int)pow(10, floor(log10(n)) - t),
               n / (int)pow(10, floor(log10(n)) - t) % 10);
        printf("%d-----%d\n", (n / (int)pow(10, floor(log10(n)) - t) % 10), t);
        t++;
    }
    return 0;
}

I've modified the loop condition; the old-style Fortran II arithmetic if condition really isn't good style in C. It also prints the last digit. It would be better if the loop were written for (int t = 0; t <= d; t++), but I've not made that change.

On a Mac running OS X 10.10.3, using GCC 5.1.0 compiling a 64-bit program, the result is:

n = 125521: 6 Digits
t = 0: n = 125521; L = log10(n) = 5.098716; F = floor(L) = 5.000000
       T = F-t = 5.000000; P = pow(10,T)= 100000.000000
       I = (int)P = 100000; D = n/I = 1; M = D % 10 = 1
1-----0
t = 1: n = 125521; L = log10(n) = 5.098716; F = floor(L) = 5.000000
       T = F-t = 4.000000; P = pow(10,T)= 10000.000000
       I = (int)P = 10000; D = n/I = 12; M = D % 10 = 2
2-----1
t = 2: n = 125521; L = log10(n) = 5.098716; F = floor(L) = 5.000000
       T = F-t = 3.000000; P = pow(10,T)= 1000.000000
       I = (int)P = 1000; D = n/I = 125; M = D % 10 = 5
5-----2
t = 3: n = 125521; L = log10(n) = 5.098716; F = floor(L) = 5.000000
       T = F-t = 2.000000; P = pow(10,T)= 100.000000
       I = (int)P = 100; D = n/I = 1255; M = D % 10 = 5
5-----3
t = 4: n = 125521; L = log10(n) = 5.098716; F = floor(L) = 5.000000
       T = F-t = 1.000000; P = pow(10,T)= 10.000000
       I = (int)P = 10; D = n/I = 12552; M = D % 10 = 2
2-----4
t = 5: n = 125521; L = log10(n) = 5.098716; F = floor(L) = 5.000000
       T = F-t = 0.000000; P = pow(10,T)= 1.000000
       I = (int)P = 1; D = n/I = 125521; M = D % 10 = 1
1-----5

You should run either this program or something very similar and show the results of the intermediate calculations. We can then, maybe, begin to understand why you see a 7 instead of a 5.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278