(Это для упражнения) Я пытаюсь создать программу, которая принимает двойной, как 1.2041, и превращает каждую десятичную цифру в элемент в массиве.
Через цикл я хочу, чтобы массив завершился следующим образом: ar[0] = 0.2; ar[1] = 0.00; ar[2] = 0.004; ar[3] = 0.0001;
ar[0] = 0.2; ar[1] = 0.00; ar[2] = 0.004; ar[3] = 0.0001;
После этого я собираюсь добавить десятичные числа вместе и в итоге получится 0,2041, но я не могу найти способ найти доступ к каждому десятичному знаку в одиночку.
Я пытался с умножением и вычитанием, но я не могу заставить его работать.
Кто-нибудь знает простой способ сделать каждое десятичное число двойным в своих отдельных элементах в массиве?
Если вы не заинтересованы в реализации Dragon4 (см. "Как напечатать числа с плавающей запятой в точности" Гая Л.Стейле-младшего и Джона Л. Уитта), вам было бы лучше отформатировать double
значение в строку, например, используя std::to_string()
и вычислить соответствующее значение знака [приближения].
При представлении десятичного значения с дробными цифрами в double
который обычно представляется с использованием двоичного представления с плавающей запятой, значение обычно округляется. Например, невозможно точно представить 0.1
используя double
. Вместо этого будет сохранено ближайшее отображаемое значение. При использовании соответствующего алгоритма для восстановления десятичного представления, например, Dragon4 или Grisu (где последнее обычно быстрее, но иногда возвращается к Dragon4, насколько я понимаю) учитывается исходное округление. Эти алгоритмы несколько нетривиальны. Вы можете найти источник вариации Dragon4 в dtoa.c
Дэвидом Гей. Вы можете взглянуть на более подробную информацию в статье. Здесь будут драконы: прогресс в проблемах, о которых вы даже не знали.
Когда вы используете наивный подход, пытающийся вывести каждую цифру, вы получите значение, но в лучшем случае вы получаете значение, фактически представленное double
. Например, ваше значение 1.2041
представлено как 1.204099999999999948130380289512686431407928466796875
. Самый простой способ увидеть, как представлено представление, - использовать анализ IEEE-754: получить два анализатора, ввести значение в первое, принять шестнадцатеричное представление (в вашем случае 3FF343FE5C91D14E
) и выгрузить его во второй. Он покажет точное десятичное значение, используемое double
.
Если умножить на 10 ^ n и превратить результат в int, вы получите целое число до желаемого десятичного числа. Если вы затем получите остаток от этого числа, деленного на 10, вы получите только номер.
Затем вы делите с 10 ^ n и получите десятичное значение:
(double)((int)(number/pow(10,n))%10)/pow(10,n)
Это должно делать свое дело.
ПРИМЕЧАНИЕ. Этот код требует "math.h", число - это целое число, а n - десятичное. n = 1 - первое десятичное число.
Примечание 2: Как отметил Дитмар Кюль, этот код имеет проблемы с последним десятичным знаком, как можно увидеть здесь: http://ideone.com/xOracn Я ищу обходное решение или исправление.
1.2045
(вы можете легко попробовать вывести std::cout << int(x * 10) << '\n';
где x
инициализируется до 1.2045
(обратите внимание, что используется константа вероятно, даст правильное значение, потому что постоянное сворачивание компиляторами стало слишком хорошим, однако с динамическим значением вы получите неправильные результаты.) Также обратите внимание, что вы не можете спасти результат, например, добавив 0.5
: хотя это исправит некоторые ценности это сломают другие.
double
.
ar[0] = 0,2
не назначает 0.2 для 0-го элемента массива. Это оператор запятой; он присваивает0
элементу массива, а затем оценивает2
(что не работает). Используйте.
вместо десятичной точки вместо. Кроме того,fmod()
(и / илиmodf()
).