Это стандартная проблема из-за того, как компьютер хранит значения с плавающей точкой. Найдите здесь «проблему с плавающей точкой», и вы найдете массу информации.
Вкратце - поплавок/двойной не может точно хранить 0,1. Это будет всегда немного.
Вы можете попробовать использовать тип decimal
, который хранит числа в десятичной системе. Таким образом, 0,1 будет представиться точно.
Вы хотели бы знать причину:
Float/двойной хранятся в виде двоичных дробей, а не десятичные дроби. В качестве иллюстрации:
12.34 в десятичной системе счисления (то, что мы используем) означает 1 * 10 + 2 * 10 + 3 * 10 -1 + 4 * 10 -2 . Компьютер хранит числа с плавающей точкой таким же образом, за исключением того, что использует базу 2: 10.01 означает 1 * 2 + 0 * 2 + 0 * 2 -1 + 1 * 2 -2
Теперь, вы, наверное, знаете, что есть некоторые цифры, которые не могут быть представлены в полном объеме с нашей десятичной нотации. Например, 1/3 в десятичной нотации составляет 0,33333333 ... То же самое происходит в двоичной нотации, за исключением того, что цифры, которые не могут быть представлены точно, различны. Среди них номер 1/10. В двоичной записи, которая составляет 0,000110011001100 ...
Поскольку двоичная запись не может хранить ее точно, она сохраняется округленным образом. Отсюда и ваша проблема.
Можете вы добавить свое объявление о двойнике, пожалуйста? –
http://stackoverflow.com/questions/753948/why-is-floating-point-arithmetic-in-c-imprecise –
Всестороннее чтение по теме: [Что должен знать каждый компьютерный ученый о арифметике с плавающей запятой] (http://docs.sun.com/source/806-3568/ncg_goldberg.html) –