Числа представлены в базе 2, а значения с плавающей точкой в базе 2 не могут точно представлять каждое десятичное значение в базе. То, что вы вводите как 23.8
, преобразуется в его ближайшее эквивалентное значение base-2, которое не совсем 23,8. Когда вы распечатываете это приблизительное значение, оно печатается как 23.7999
.
Вы также используете float
, который является наименьшим типом с плавающей запятой и имеет только 24 бита точности (примерно 7 десятичных цифр). Если вы переключитесь на double
, количество битов точности более чем удваивается от float
, поэтому разница между десятичным значением, например 23,8, и его представлением double
будет намного меньше. Это может позволить процедуре печати лучше выполнить округление, чтобы вы видели 23.8
с double
. Однако фактическое значение в переменной все еще не совсем 23,8.
Как общий совет, если у вас нет огромного количества значений с плавающей запятой (что делает использование памяти вашей основной задачей), лучше использовать double
всякий раз, когда вам нужен тип с плавающей запятой. Вы не избавляетесь от всего странного поведения, но вы увидите его меньше, чем с float
.