-8

Is there a way to get the number of digits without the division by 10?

For example i have this:

int main()
{
  int dividend = 100;
  int remainder=0;
  int temp = 0;

  while(dividend>=10)
  {
    dividend = dividend-10;
    temp+=1;
  }
  printf("Quotient: %d\n",temp);
  printf("Reminder: %d\n",dividend);
}

And now I will add to calculate the number of digits of the variable dividend.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
Abc
  • 15
  • 3
  • 4
    How is `dividend-10` serving any purpose _here_? – Sourav Ghosh Mar 29 '18 at 08:37
  • Shouldn't it be `dividend / 10` instead of `dividend-10` in first place? – Jabberwocky Mar 29 '18 at 08:39
  • 3
    Convert to string and count the characters... beware of the `-` sign. Good luck with your homework ;-) – Stefan Mar 29 '18 at 08:40
  • 2
    BTW: what's wrong with dividing by 10? That's the most efficient method. – Jabberwocky Mar 29 '18 at 08:41
  • 1
    @NickA Better then to divide by 2 and then divide by 5 to avoid rounding problems. Either way though, that's just re-implementing division by 10, which is basically what all alternative approaches will end up doing too. –  Mar 29 '18 at 08:43
  • @hvd bah of course, i was thinking no division rather than no division by 10, right enough – Nick is tired Mar 29 '18 at 08:43
  • Consider what a logarithm is. That's a HINT. – Peter Mar 29 '18 at 08:43
  • 1
    multiply by 10 until your number is less that `10**n`. – Jarod42 Mar 29 '18 at 08:44
  • You could even do this with some if statements, considering the limited maximum of an int. Calculations would be minimal XD – Stefan Mar 29 '18 at 08:45
  • The thing is that I have to rewrite this C program then in Assembler Langugae. And I have only limited commands to use (add, sub, bitwise and bitshifting) - that's why I do not want to divison / 10. – Abc Mar 29 '18 at 08:46
  • You can always just loop from 1 to whatever the maximum of the typesize is and increment your loop counter by `*= 10` until your bracket the number your are determining the length for. – David C. Rankin Mar 29 '18 at 08:57
  • @DavidC.Rankin how do you mean that? – Abc Mar 29 '18 at 09:00
  • It's "remainder", not "reminder". – Lightness Races in Orbit Mar 29 '18 at 09:04
  • So this is the question you were trying to ask: "is it possible to divided by 10 with bit shifting?" The answer: https://stackoverflow.com/questions/5284898/implement-division-with-bit-wise-operator – SiggiSv Mar 29 '18 at 09:17
  • @Abc, it is doing the same thing that the answer you chose (in a slightly more compact and efficient manner). Say you want the number of digits in `v`, (`int ndigits = 0;`) then `for (int i = 1; i < v; i *= 10) ndigits++;` Now `ndigits` holds the number of characters and you simply add `1` for the string storage requirement. One iteration per-digit and simply multiply current by 10, no division. Prior to loop you test if value is negative and add `1` for the sign and keep a flag to prefix the output with `-` when you are done. – David C. Rankin Mar 29 '18 at 10:23

5 Answers5

3

If you are allowed to use logarithms then

int i = 123456;
int digitsCount = ceil(log10(abs(i)+1.0));
cout << digitsCount;

6

Yola
  • 18,496
  • 11
  • 65
  • 106
  • 3
    That won't work for all integers though. It gives an off-by-one answer for 1, 10, 100, etc. and probably a strange answer for 0. You could use `int digitsCount = ceil(log10(abs(i) + 1));` – Ian Abbott Mar 29 '18 at 09:07
  • @IanAbbott Cool! – Yola Mar 29 '18 at 09:12
  • Well perhaps it would be better to replace `+1` with `+1.0` (or replace `abs` with `fabs`) to avoid arithmetic overflow. – Ian Abbott Mar 29 '18 at 09:17
  • A bit more needed for a complete solution. As is, this will give undefined behaviour for `i == INT_MAX` – Peter Mar 29 '18 at 09:33
3

You have to know the maximum range of integer to make this function usefull. no function call, no division ...

int nbDigitInteger(int number)
{
    if (-10 < number && number < 10) return (1);
    if (-100 < number && number < 100) return (2);
    if (-1000 < number && number < 1000) return (3);
    if (-10000 < number && number < 10000) return (4);
    if (-100000 < number && number < 100000) return (5);
    ...
}

Sometime, the simplier is the best.

Tom's
  • 2,448
  • 10
  • 22
  • Check the operator for negative numbers. And using `abs()` will save some comparisons. Further you can avoid linear search and use halving method (bisection) to reduce number of `if`s run, if you want to be uber-fast. – qrdl Mar 29 '18 at 09:36
  • what happen for abs(INT_MIN) ? Yes, using dichotomie will be faster, but you have to write 4 condition if you doesn't use abs, and I dont want to use it since abs(INT_MIN) will be wrong. – Tom's Mar 29 '18 at 09:46
1

Your question is too broad, and the code is also unrelated.

Since you attempted to post the code, I'll provide the guidelines for the problem you asked for. Write the code yourself.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

An alternative to the very elegant solution o @Yola is this.

intPow10 is returning 10 to the power exponent. I did not use pow from math.h, since it is numerically expensive and as @Tom's pointed out it can lead to invalid results.

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

int intPow10(int exponent){
    int retval=1;
    while (exponent){
        retval *=10;
        exponent --;
    }
    return retval;
}

int numDigits(const int i) {
    int digits = 1;
    while (intPow10(digits) <= fabs(i)) {
        digits++;
    }
    printf("%i has %i digits.\n", i,digits);
    return digits;
}

int main() {
    numDigits(1);
    numDigits(-1);
    numDigits(10);
    numDigits(13);
    numDigits(-112312);
}
schorsch312
  • 5,553
  • 5
  • 28
  • 57
  • it is very important to use no other functions because i will rewrite this C programm in Assembler language and there a limited commands that i can use. – Abc Mar 29 '18 at 08:55
  • pow return a double, and pow(10,2) can return '"99,9999999" and will provide false result. Also, you call the function "fabs" each loop, that's unnecessary. Just do " i = fabs(i);" before the while loop. – Tom's Mar 29 '18 at 08:56
  • 3
    @Abc "because i will rewrite this C programm in Assembler language" - Oh FFS. Ask what you're actually interested in in the *question*, not after people have wasted their time by answering a question you weren't interested in. When you will rewrite this in assembly, that has a massive impact on what kind of code is acceptable and what kind of tricks to avoid division are appropriate. Look at what compilers turn `int f(int x) { return x / 10; }` into: they don't all issue a division instruction. You can investigate what they do and see if you can understand why it works, and if not, ask. –  Mar 29 '18 at 09:05
  • @hvd is it possible to divided by 10 with bit shifting? – Abc Mar 29 '18 at 09:14
0

Is this code golf or what?

int b = 1000;
char a[10] = itoa(b);
printf("%d\n", strlen(a)); // 4

This simply turns b into a string, which is a. Then, prints the length. What would we do without atoi() and itoa()? Our own functions!

Steve Woods
  • 227
  • 1
  • 9
  • doesn't work if "int b = -10;", doesn't work for 64bit integer. – Tom's Mar 29 '18 at 09:12
  • @Tom's A negative number (-10) is a positive number (65525 in 16-bit). It should do. Let the OP try it out, shall we? To be quite honest, I haven't really tested it. I've just thought of it. – Steve Woods Mar 29 '18 at 09:15
  • What I mean is "-10" is 2 digit, but strlen will return 3. And to be frank, i know that C language have some mathematically subtility (like "13.4 / 3 * 3" will not forcibly be 13.4), but to the point that a "negative number is positive number" ? Even with integer overflow, how "-10" can be "65525" ? Or I misunderstand what you said ? – Tom's Mar 29 '18 at 09:29
  • @Tom's now I know what you mean but I don't think he really wants to work with negative numbers. He can always strip the character if he wants. Anyway, with the CPU, you can't really use (-) in machine code. For example, we don't have -0x10. Instead, we have the maximum positive number and go backwards. The sign bit helps us out a little, which is given by the CPU, to tell us it's positive or negative. Sorry if it's confusing. – Steve Woods Mar 29 '18 at 09:35
  • Well, if he doesn't want negative number, then it should be "unsigned", not "int", so we have to manage the negative number. Yes, I agree that there is no "negative" number directly in the hardware : I understand now what you mean. It's like casting "-10" into an "unsigned" : it all come down on how we interpret the stored bit. It was confusing for me, but thanks to clarify it. I didn't understand it the first time. – Tom's Mar 29 '18 at 09:41