Как я могу сделать мой Get_Numb_of_Digits_in_a_number (функция) более точная?


Вот моя функция, но она иногда имеет непредсказуемые результаты ввода разных номеров, но с одинаковым количеством цифр, получая разные результаты. Я думаю, что это как-то связано с компьютерами неточное сохранение десятичного технике, но я хотел бы знать, как сделать его более точным.

///////////////////////     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;
};


245
3
c++
задан 15 мая 2011 в 06:05 Источник Поделиться
Комментарии
1 ответ

Чтобы получить количество целых чисел, вы можете просто использовать метод log10.

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

Я реализовал функции в C#. С помощью десятичного типа для расчета цифр после десятичного знака, точности вопросы будут автоматически решены. Скорее всего, простой цикл for является более эффективным, чем использование военнопленных как в вашем решении. Результатом цифр после десятичного знака для бесконечного точные цифры (например, ПИ) зависит от точности типа. С этот код, я получаю 14 цифр после запятой в ПИ.

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;
}

Вы должны спросить себя, где вы будете использовать этот код. Когда вы собираетесь использовать его, чтобы вычислить правильный отступ для вывода строки, он, вероятно, лучше всего преобразования чисел в строки и количество символов. Это был бы интересный сравнительный тест, чтобы сравнить, что решение это одно.

3
ответ дан 15 мая 2011 в 12:05 Источник Поделиться