Деление с плавающей точкой a/b
не является математическим делением a ÷ b , за исключением очень редких * обстоятельств.
Как правило, деление с плавающей запятой a/b
равно a ÷ b + ε.
Это верно по двум причинам.
Числа с плавающей точкой (за исключением редких случаев) являются приблизительными значениями десятичного числа.
a
- это a + εa.
b
- это b + εb.
Числа с плавающей запятой используют основную кодировку цифр 2 справа от десятичного разряда. Когда вы пишете 3.1
, это расширяется до приближения по основанию 2, которое отличается от реального значения на небольшое количество.
Кстати, реальные десятичные числа имеют ту же проблему. Запишите десятичное расширение 1/3. К сожалению. Вы должны прекратить писать десятичные разряды в какой-то момент. Двоичные числа с плавающей запятой имеют ту же проблему.
Деление имеет фиксированное количество двоичных разрядов, что означает усеченный ответ. Если есть повторяющийся двоичный шаблон, он прерывается. В редких случаях это не имеет значения. В общем, вы ввели ошибку, выполнив деление.
Поэтому, когда вы делаете что-то подобное, многократно добавляйте 1/k
значения, которые вы вычисляете
1 ÷ k + ε
И добавляя их. Ваш результат (если вы имели право range
) будет
n × (1 ÷ k + ε) = n ÷ k + n × ε
Вы умножили небольшую ошибку ε на n . Делать это большой ошибкой. (За исключением редких случаев.)
Это плохо. Очень плохой. Все деление с плавающей точкой вводит ошибку. Ваша задача как программиста - сделать алгебру, чтобы избежать или отложить деление, чтобы предотвратить это. Хороший дизайн программного обеспечения означает хорошую алгебру для предотвращения ошибок, вносимых оператором деления.
[* Редкие случаи. В редких случаях маленькая ошибка оказывается равной нулю. Редкие случаи происходят, когда ваши значения с плавающей запятой представляют собой небольшие целые числа или дроби, которые представляют собой суммы степеней двух 1/2, 1/4, 1/8 и т. Д. В редком случае, когда у вас есть доброкачественное число с доброкачественным дробным числом часть, ошибка будет равна нулю.]