Вот ключ к вашему затруднению: 10
является продуктом 2
и 5
. Вы можете представить любое число точно в десятичных десятичных числах, то есть k * 1/2 n * 1/5 m где k
, n
и m
являются целыми числами.
Альтернативно формулируется - если число n
в 1 / n содержит фактор, который не является частью факторов базы, число не сможет быть точно представлено в фиксированном количестве цифр в двоичном / десятичном / любом другом разложении этого номер - он будет иметь повторяющуюся часть. Например, 1/15 = 0,0666666666 .... потому что 3 (15 = 3 * 5) не в 10 раз.
Таким образом, все, что может быть представлено в базе 2 точно (k * 1/2 n ), может быть точно представлено в базе 10.
Помимо этого, существует проблема того, сколько цифр / битов вы используете для представления числа. Есть некоторые числа, которые могут быть точно представлены в некоторой базе, но для этого требуется больше, чем некоторое количество цифр / бит.
В двоичном формате число 1/10, которое обычно равно 0,1 в десятичном виде, не может быть представлено как число, которое может быть представлено в фиксированном количестве битов в двоичном формате. Вместо этого число равно 0,00011001100110011 ... 2 (часть 0011 повторяется вечно).
Давайте посмотрим на число 1 2 /1010 2 немного более близко.
____
0,00011
+ ---------
1010 | 1,00000
0
-
1 0
0
----
1 00 --------- +
0 |
----- |
1 000 |
0 |
------ | повторяющий
1 0000 | блок
1010 |
------ |
1100 |
1010 |
---- |
100 ---- +
Это то же самое, что вы получаете, когда пытаетесь сделать длинное деление на 1/3.
1/10, когда факторинг равен 1 / (2 1 * 5 1 ). Для основания 10 (или любого кратного 10) это число заканчивается и называется обычным числом . Повторяющаяся десятичная дробь известна как повторяющаяся десятичная дробь , и те числа, которые продолжаются вечно без повторения, являются иррациональными числами.
Математика за этим углубляется в малые теоремы Ферма ... и как только вы начинаете говорить Ферма или теорема, это становится Math.SE вопрос .
Существуют ли числа, которые не представлены в базе 10, но могут быть представлены в базе 2?
Ответ - нет'.
Итак, в этот момент нам всем должно быть ясно, что каждое двоичное разложение фиксированной длины рационального числа может быть представлено как десятичное разложение фиксированной длины.
Давайте внимательнее посмотрим на десятичную в C #, которая приводит нас к десятичной с плавающей запятой в .NET и, учитывая автора, я согласен, вот как это работает.
Десятичный тип имеет те же компоненты, что и любое другое число с плавающей запятой: мантисса, показатель степени и знак. Как обычно, знак только один бит, но есть 96 бит мантиссы и 5 бит экспоненты. Однако не все комбинации показателей действительны. Работают только значения 0-28, и все они фактически отрицательны: числовое значение равно . Это означает, что максимальные и минимальные значения типа составляют +/- (2 96 -1), а наименьшее ненулевое число по абсолютной величине равно 10 -28 .sign * mantissa / 10exponent
Я сразу укажу, что из-за этой реализации есть числа в double
типе, которые не могут быть представлены в decimal
- те, которые находятся вне диапазона. Double.Epsilon
это то, 4.94065645841247e-324
что не может быть представлено в decimal
, но может быть в double
.
Однако в пределах диапазона, который может представлять десятичная дробь, он обладает большей точностью, чем другие нативные типы, и может представлять их без ошибок.
Есть несколько других типов, плавающих вокруг. В C # есть BigInteger, который может представлять произвольно большое целое число. Там нет никакого эквивалента в Java BigDecimal (который может представлять числа с десятичными цифрами до 2 32 цифр длинных - что является значительным диапазон) точно . Тем не менее, если вы немного поковыряетесь, вы сможете найти ручные реализации.
Есть некоторые языки, которые также имеют рациональный тип данных, который позволяет вам точно представлять рациональные значения (так что 1/3 фактически равна 1/3).
Специально для C # и выбора числа с плавающей точкой или рационального, я буду откладывать на Jon Skeet из плавающей десятичной точки в .NET :
Большинство бизнес-приложений, вероятно, должны использовать десятичные, а не с плавающей или двойной. Мое эмпирическое правило заключается в том, что искусственные ценности, такие как валюта, обычно лучше представить с десятичной плавающей запятой: например, концепция ровно 1,25 доллара вполне разумна. Для значений из мира природы, таких как длины и веса, двоичные типы с плавающей запятой имеют больше смысла. Несмотря на то, что существует теоретический «ровно 1,25 метра», в реальности этого никогда не произойдет: вы, безусловно, никогда не сможете измерить точные длины, и вряд ли они вообще существуют на атомном уровне. Мы привыкли к определенной терпимости.