2014-10-24 13 views
-1

Я пытаюсь получить число цифр после десятичной точки в двойном. В настоящее время мой код выглядит следующим образом:Определение числа десятичных цифр в двойном - C++

int num_of_decimal_digits = 0; 
while (someDouble - someInt != 0) 
{ 
    someDouble = someDouble*10; 
    someInt = someDouble; 
    num_of_decimal_digits++; 
} 

Всякий раз, когда я вхожу в дробной для someDouble, что меньше, чем один, цикл застревает и повторяет бесконечно. Должен ли я использовать static_cast? Любой совет?

+0

На этот вопрос почти нет значимого ответа. Это в значительной степени зависит от вас, чтобы определить, сколько мест может быть значительным и действовать соответствующим образом. –

+0

** - 1 ** Если ваши версии с плавающей точкой реализации C++ не основаны на десятичном представлении (в отличие от целых, это разрешено, но очень редко), вопрос не имеет смысла. –

ответ

1

Из-за ошибки округления с плавающей точкой умножение на 10 не обязательно является точным десятичным сдвигом. Вы можете проверить абсолютную ошибку разницы, а не сравнивать ее для точного равенства с 0.

while (abs(someDouble - someInt) < epsilon) 

Или вы можете подтвердить, что двойной с 53-битной мантиссы может представлять только войти ≈ 15,9 десятичных цифр, а также ограничить цикл до 16 итераций.

while (someDouble - someInt != 0 && num_of_decimal_digits < 16) 

Или оба.

while (abs(someDouble - someInt) < epsilon && num_of_decimal_digits < 16) 
0

Наивный ответ был бы:

int num_of_decimal_digits = 0; 
double absDouble = someDouble > 0 ? someDouble : someDouble * -1; 
while (absDouble - someInt != 0) 
{ 
    absDouble = absDouble*10; 
    someInt = absDouble; 
    num_of_decimal_digits++; 
} 

Это решает проблему отрицательных чисел.

Однако это решение, скорее всего, не даст вам желаемого результата во многих случаях из-за того, как представлены числа с плавающей запятой. Например, 0.35 действительно может быть представлено как 0.3499999999998, как номера с плавающей точкой хранятся в двоичном формате. Я бы предложил вам поделиться дополнительной информацией о том, что вы надеетесь выполнить с помощью этого кода (ваш ввод и ваш желаемый результат). Вероятно, гораздо лучшее решение для того, что вы пытаетесь выполнить.

+0

0.3499999999998 не является точно представимым в 64-битной двоичной плавающей точке IEEE, наиболее распространенным вариантом для двойного. Ближайшее представимое значение до 0,35 равно 0,34999999999999997779553950749686919152736663818359375, что, если что-то усиливает вашу точку. –