В моей программе есть один массив с 25 двойными значениями 0,04 Когда я пытаюсь суммировать эти значения в цикле, я получаю следующие результаты:
0.0 + 0.04 = 0.04
0.04 + 0.04 = 0.08
0.08 + 0.04 = 0.12
0.12 + 0.04 = 0.16
0.16 + 0.04 = 0.2
0.2 + 0.04 = 0.24000000000000002
0.24000000000000002 + 0.04 = 0.28
0.28 + 0.04 = 0.32
0.32 + 0.04 = 0.36
0.36 + 0.04 = 0.39999999999999997
0.39999999999999997 + 0.04 = 0.43999999999999995
0.43999999999999995 + 0.04 = 0.4799999999999999
0.4799999999999999 + 0.04 = 0.5199999999999999
0.5199999999999999 + 0.04 = 0.5599999999999999
0.5599999999999999 + 0.04 = 0.6
0.6 + 0.04 = 0.64
0.64 + 0.04 = 0.68
0.68 + 0.04 = 0.7200000000000001
0.7200000000000001 + 0.04 = 0.7600000000000001
0.7600000000000001 + 0.04 = 0.8000000000000002
0.8000000000000002 + 0.04 = 0.8400000000000002
0.8400000000000002 + 0.04 = 0.8800000000000002
0.8800000000000002 + 0.04 = 0.9200000000000003
0.9200000000000003 + 0.04 = 0.9600000000000003
Какого черта такое могло случиться ?!




Наиболее распространенное хранилище значений с плавающей запятой в языках программирования - IEEE одиночные и парные разряды - не имеет точного представления для большинства десятичных дробей.
Причина в том, что они хранят значения в двоичном формате с плавающей запятой, а не в десятичном формате с плавающей запятой. Единственные дробные значения, которые могут быть представлены точно, - это суммы отрицательных степеней двойки. Цифры вроде:
И т.п.
То, что вы видите, - это тот факт, что представления чисел, таких как 0,96, не могут быть точно представлены, потому что они не могут быть выражены как сумма отрицательных степеней двойки. Таким образом, при распечатке с полной точностью в виде десятичной дроби они не будут соответствовать исходному значению.
«Вместо десятичной дроби» как бы дает неправильное представление. Если бы он использовал десятичную дробь, он был бы ограничен дробными значениями, которые представляют собой суммы отрицательных степеней десяти, так что это не решит много. Кто-то, читающий ваш ответ, может подумать, что «проблема исчезла бы, если бы они использовали только base10».
@jalf, правда, но хотя бы десятичное представление с плавающей запятой удивило бы меньше людей, привыкших к простому карманному учету. Сложить стопку в 20 центов и не получить ровно один доллар - это удивительно для многих. Десятичная система счисления поможет в этом случае правильно и заменит ее на забавные проблемы с числами, которые должны быть знакомы с уроков арифметики в начальной школе.
См. Также «Что должен знать каждый компьютерный ученый о плавающей запятой»
Этот документ очень сложен для тех, кто плохо знаком с представлением с плавающей запятой в большинстве языков программирования. Я бы не рекомендовал это людям, у которых есть хотя бы год, если не три, в образовании CS.
Я согласен. С другой стороны, практикам-самоучкам и отличникам приятно знать, где он находится, на случай, если они столкнутся с числовыми проблемами.
Это все еще то, что люди должны знать, даже если он слишком сложен для чтения. ;)
В других ответах упоминалось, почему, но не как этого избежать.
Есть несколько решений:
numeric в SQL), вы можете его использовать.Вы можете попробовать класс java BigDecimal в качестве альтернативы float и double.
В некотором роде вопрос: stackoverflow.com/questions/327020/…