Ok. Позвольте мне попытаться объяснить это.
Основная вещь, которую следует помнить с числами с плавающей запятой, заключается в следующем: они занимают ограниченное количество бит и пытаются представить исходное число, используя арифметику base-2.
Как известно, в базовых 2 арифметических целых числах представлены степени 2, которые они содержат. Таким образом, 6 будет представлено как 4 + 2, т. Е. в двоичном формате как 110.
Чтобы понять, как представлены дробные числа, вы должны подумать о том, как мы представляем дробные числа в нашей десятичной системе. Дробная часть чисел (например, 0.11) представлена в виде кратных обратных степеней 10 (так как основание равно 10). Таким образом, 0.11 фактически составляет 1/10 + 1/100. Как вы понимаете, это недостаточно мощно, чтобы представлять все дробные числа в ограниченном количестве цифр. Например, 1/3 будет 0,333333 .... в бесконечном порядке. Если бы у нас было всего 32 цифры пробела, чтобы записать число вниз, мы получим только приблизительное значение к исходному числу, 0.3333333333333333333333333333333333. Это число, например, дало бы 0.9999999999999999999999999999999999, если бы оно было умножено на 3, а не 1, как вы ожидали.
Ситуация аналогична в базе-2. Каждое дробное число будет представлено как кратность обратных степеней 2. Таким образом, 0,75 (в десятичной форме) (т. Е. 3/4) будет представлено как 1/2 + 1/4, что будет означать 0.11 (в базе-2). Так же, как база 10 не может достаточно представить каждое дробное число конечным образом, base-2 не может представлять все дробные числа при ограниченном пространстве.
Теперь, попытайтесь представить 0.11 в базе-2; вы начинаете с 11/100 и пытаетесь найти обратную силу 2, которая меньше этого числа. 1/2 не работает, 1/4 нет 1/8. 1/16 подходит для счета, поэтому вы отмечаете 1 на 4-м месте после десятичной точки и вычитаете 1/16 от 11/100. Осталось 19/400. Теперь попробуйте найти следующую мощность 2, которая соответствует описанию. 1/32, кажется, что один, отмечают 5-е место после точки и вычитать 1/32 из 19/400, вы получите 13/800. Затем один 1/64, и вы остались с 1/1600, таким образом, следующий все пути вверх по 1/2048 и т.д. и т.п. Таким образом, мы получили, насколько 0.00011100001, но он идет снова и снова; и вы увидите, что всегда остается остаток. Теперь я не прошел весь расчет, но после того, как вы поместили 32 бинарных цифры после точки, вы, вероятно, по-прежнему будете иметь некоторую долю слева (и это предполагает, что все 32 бита пространства расходуются, представляя десятичную часть, которой это не так). Таким образом, я уверен, что вы можете оценить, что итоговое число может отличаться от его фактической стоимости на какую-то сумму.
В вашем случае разница составляет 0,00000000000000001, что составляет 1/100000000000000000 = 1/10^17, и я уверен, что вы можете понять, почему у вас может быть это.
ok. Я не знаю почему. но как его решить? – Simon
вы еще не решили проблему. – lincolnk