Почему я не могу умножить плавание? [дубликат]

7
задан Community 23 May 2017 в 12:04
поделиться

6 ответов

Во-первых, вы можете умножать плавающие числа. Проблема заключается не в самом умножении, а в исходном числе, которое вы использовали. Умножение может потерять некоторую точность, но здесь исходное число, которое вы умножили, начало с потерянной точности.

На самом деле это ожидаемое поведение. floatы реализованы с использованием двоичного представления, что означает, что они не могут точно представлять десятичные значения.

Дополнительную информацию см. в MSDN.

Вы также можете увидеть в описании float, что он имеет точность 6-7 значащих цифр. В вашем примере, если вы округлите 31.099998 до 7 значащих цифр, вы получите 31.1, так что здесь все работает, как и ожидалось. Тип

double, конечно, будет более точным, но все же имеет ошибку округления из-за двоичного представления, в то время как число, которое вы написали, является десятичным.

Если вы хотите получить полную точность для десятичных чисел, вам следует использовать тип decimal. Такой тип существует в таких языках, как C#. http://msdn.microsoft.com/en-us/library/system.decimal.aspx

Вы также можете использовать рациональное представление чисел. Использование двух целых чисел даст вам полную точность, пока вы можете представить число как деление двух целых чисел.

14
ответ дан 6 December 2019 в 06:49
поделиться

Это работает, как и ожидалось. Компьютеры имеют конечную точность, потому что они пытаются вычислить значения с плавающей запятой из целых чисел. Это приводит к неточностям плавающей точки.

На странице Википедии с плавающей точкой гораздо более подробно описано представление и возникающие проблемы с точностью, чем я мог бы рассказать здесь :)

Интересное побочное замечание: это частично является причиной того, почему многие денежные вычисления выполняются с использованием целых чисел (центов) - не позволяйте компьютеру терять деньги из-за недостаточной точности! Я хочу свои $0.00001!

5
ответ дан 6 December 2019 в 06:49
поделиться

Число 3.11 не может быть представлено в двоичном виде. Самое близкое, что можно получить с 24 значащими битами, это 11.0001110000101000111101, что в десятичной системе равно 3.1099998950958251953125.

Если ваше число 3.11 должно представлять денежную сумму, то вам нужно использовать десятичное представление.

4
ответ дан 6 December 2019 в 06:49
поделиться

В сообществах Python мы часто видим, как люди удивляются этому, поэтому есть хорошо протестированные и отлаженные разделы FAQs и учебные разделы ] по проблеме (конечно, они сформулированы в терминах Python, а не C, но поскольку Python в любом случае делегирует арифметику с плавающей запятой на базовый C и оборудование, все описания механики с плавающей запятой по-прежнему применимы).

Это, конечно, не вина умножения - удалите оператор, в котором вы умножаете nb , и вы все равно увидите похожие проблемы.

2
ответ дан 6 December 2019 в 06:49
поделиться

Из статьи в Википедии :

Тот факт, что числа с плавающей запятой не может точно представить все реальные числа, и что с плавающей запятой операции не могут точно представить истинные арифметические операции, приводит к много удивительных ситуаций. Это связанных с конечной точностью с какие компьютеры обычно представляют числа.

1
ответ дан 6 December 2019 в 06:49
поделиться

Плавающие точки не точны, потому что они используют основание 2 (потому что оно двоичное: либо 0, либо 1) вместо основания 10. А преобразование основания 2 в основание 10, как многие уже говорили, приведет к проблемам с точностью округления.

0
ответ дан 6 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: