Используйте дроби, чтобы решить неточность десятичного числа

Если десятичные числа не могут быть представлены в двоичном виде, то почему компьютеры не хранят числа как доли двух целых чисел, которые МОЖЕТ быть точно представлены?

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

Это должно в корне решить проблему неточности, но не все так гениально, так что же не так с теорией?

например вы хотите сохранить число 0,1 и использовать его для дальнейших вычислений. Вместо того, чтобы хранить его как 0,1, вы сохраняете его как 1/10 (поэтому вам нужно еще несколько байтов для хранения дробей). Затем, если вам нужно умножить его на другое число, скажем, на 5, вы также умножаете ошибку на 3. Если вы умножаете 1/10 на 3, вы получаете 1/10*3 = 3/10. Всякий раз, когда вам нужно отобразить его, 3/10 может стать неточным. До этого времени не может быть и речи о неточности.


person Bas Kuunk    schedule 05.09.2016    source источник
comment
Существующие форматы с плавающей запятой легко и быстро использовать для вычислений, а также их легко реализовать на аппаратном уровне. Также они довольно компактны, что было еще важнее во времена создания форматов.   -  person Some programmer dude    schedule 05.09.2016
comment
Попробуйте вычислить сумму 1/k для достаточно больших k, меньших n, и вы увидите, что размер (в битах) вашего знаменателя является чем-то вроде экспоненциального относительно n. Формат с плавающей запятой сохраняет постоянный размер (в битах) результата такого вычисления. Даже если это приблизительно, каждое вычисление с плавающей запятой выполняется в фиксированном ограниченном хранилище и в фиксированное ограниченное время, чего нельзя сказать о точных дробях.   -  person Franck    schedule 05.09.2016


Ответы (2)


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

person Simon Byrne    schedule 05.09.2016
comment
Я написал тип BigRational, используя BigInteger в качестве числителя и знаменателя, и, как правило, BigInteger вообще не становится очень большим. - person Rudy Velthuis; 06.09.2016
comment
Хотя для чего ты его использовал? - person Simon Byrne; 07.09.2016
comment
Я написал его, чтобы помочь мне вычислить ряды Маклорена для тригонометрии BigDecimal, возведения в степень и т. д. с необходимой точностью. Но его можно использовать и как собственный тип. Обратите внимание, что это не было написано на Java, я написал BigInteger, BigDecimal и BigRational на Object Pascal (и на каком-то встроенном ассемблере). - person Rudy Velthuis; 07.09.2016

Десятичные просто не важны. Классическим вариантом использования были деньги, пока кто-то не сообразил, что можно работать с целыми центами.

Важно понимать, что реальность не отдает предпочтения никакому основанию, и уж точно не основанию, полученному из медианного числа пальцев Homo Sapiens.

Что касается отношений, они тоже не могут представлять sqrt(2) или arctan(1). И эти являются типом чисел, которые появляются на самом деле.

person MSalters    schedule 05.09.2016