3
\$\begingroup\$

Here's my function but it sometimes has unpredicted results with entering different numbers but with the same number of digits getting different results. I figure it has something to do with a computers inaccurate decimal saving tecnique but i would like to know how to make it more accurate.

///////////////////////     Numb_Digits()   ////////////////////////////////////////////////////
        enum{DECIMALS = 10, WHOLE_NUMBS = 20, ALL = 30};
    template<typename T>
unsigned long int Numb_Digits(T numb, int scope)
{       
        unsigned long int length= 0;
        unsigned long int whole_numb= (int)numb;
            // gets the number of whole numbers
        for(int mod =0; mod!=whole_numb; length++) 
            mod = whole_numb% (int)pow(10, (double)length);
        int numb_of_wholes= length-1; length= 0; bool all = false;
        double test = 0, test2= 0;
    switch(scope){
        case ALL: all = true;       // different order to avoid decimal inaccuracies
                                    // like 2.4 being 2.39999                         // 10 bil (10 zeros)
        case DECIMALS:                      numb*=10000000000;      numb-=whole_numb*10000000000;
             for(; numb != 0; length++)
                numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); 
             if(all != true) break;

        case WHOLE_NUMBS: length += numb_of_wholes;
             if(all != true) break;

        default: break;}
                                            return length;
};
\$\endgroup\$
  • 1
    \$\begingroup\$ For one, the formatting of that code looks awful. No room to breath. ;p \$\endgroup\$ – Steven Jeuris May 15 '11 at 12:51
  • \$\begingroup\$ If your code doesn't work, it shouldn't be on code review. This is a better question for stackoverflow. \$\endgroup\$ – Winston Ewert May 15 '11 at 14:23
  • \$\begingroup\$ @Winston: In this case it 'kinda' works. :) \$\endgroup\$ – Steven Jeuris May 15 '11 at 14:52
  • 1
    \$\begingroup\$ @Jeuris, kinda doesn't cut it. The FAQ makes it clear that codereview is not for debugging help. \$\endgroup\$ – Winston Ewert May 15 '11 at 18:21
  • 1
    \$\begingroup\$ Is this just 'log(n)' \$\endgroup\$ – Martin York Apr 18 '15 at 6:56
3
\$\begingroup\$

To get the number of whole numbers, you can just use log10.

int wholeNumbers = ( number == 0 ) ? 1 : (int)log10( abs( number ) ) + 1;

I implemented your function in C#. By using the decimal type for the calculation of the numbers after the decimal sign, precision issues are automatically solved. Most likely a simple for loop is more performant than using pow as in your solution. The result of numbers after the decimal sign for infinite precise numbers (like PI) is dependent on the precision of the type. With this code, I get 14 digits after comma for PI.

public static int AmountOfDigits( double number, DecimalPart decimalPart = DecimalPart.WholeNumbers )
{
    double absNumber = Math.Abs( number );
    int amountOfDigits = 0;

    // Amount of digits before decimal sign.
    if ( decimalPart == DecimalPart.WholeNumbers || decimalPart == DecimalPart.EntireDecimal )
    {
        amountOfDigits += (absNumber == 0) ? 1 : (int)Math.Log10( absNumber ) + 1;
    }

    // Amount of digits after decimal sign.
    if ( decimalPart == DecimalPart.AfterDecimalSign || decimalPart == DecimalPart.EntireDecimal )
    {
        // Use decimal for more precision!
        decimal afterDecimalSign = (decimal)absNumber;
        while ( afterDecimalSign - Math.Truncate( afterDecimalSign ) != 0 )
        {
            amountOfDigits++;
            afterDecimalSign *= 10;
        }
    }

    return amountOfDigits;
}

You do have to ask yourself where you will use this code however. When you are going to use it to calculate correct padding for string output, it's probably better to just convert the numbers to strings and count the amount of characters. It would be an interesting benchmarking test to compare that solution to this one.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.