Ваша математика с 32-битным float
с предлагает конечное значение для e
из 0.004999...
, а не "логическое" 0.005
, которое вы ожидаете (и ожидаете округления до 0.01
). Это так же, как это происходит с математикой с плавающей точкой . Округление до двух знаков после запятой точно описывает результат как 0.00
; оно меньше 0.005
, поэтому округляется до 0.00
, а не 0.01
.
Использование более точного типа (double
) может помочь (это происходит на моей машине [после изменения scanf
на использование %lf
], но многие компиляторы, особенно с более высокой оптимизацией и некоторыми архитектурами, нарушают спецификации IEEE-754 и могут не соглашаться), но в сущности математика с плавающей запятой будет приводить к ошибкам относительно точных логическая арифметика c, поэтому вам следует использовать другой подход, если вы не можете допустить даже небольших ошибок, например, математика на основе фиксированной точки int
или libmpdec
или подобное для полного десятичного (основание-10) плавающего point math.
Обратите внимание, что в зависимости от того, что вы решите делать, вам может понадобиться быть осторожным с режимом округления; C99 округляет значения на полпути от нуля, но есть и другие режимы округления (округление до половины даже является обычным из-за отсутствия смещения в округлении), которое выдает 0.00
при округлении до двух знаков после запятой, даже если Вы действительно произвели 0.005
точно.