Я определяю число с плавающей запятой как float transparency = 0.85f;
И в следующей строке я fcn_name(transparency)
ее функции – fcn_name(transparency)
– но получается, что transparency
переменной имеет значение 0.850000002
, а когда я печатаю ее с настройкой по умолчанию, она равна 0.850000002
. Для значения 0.65f
это 0.649999998
.
Как я могу избежать этой проблемы? Я знаю, что плавающая точка – это просто приближение, но если я определяю поплавок всего несколькими десятичными знаками, как я могу убедиться, что он не изменился?
Значения с плавающей запятой, представленные в двоичном формате, не имеют определенной десятичной точности. Просто потому, что вы читаете в некоторых спецификациях, что число может представлять некоторую фиксированную сумму десятичных цифр, это на самом деле мало значит. Это просто грубое преобразование физической (и значащей) бинарной точности в ее гораздо менее значимое десятичное приближение.
Одним из свойств бинарного формата с плавающей запятой является то, что он может точно представлять (в пределах своей ширины мантиссы) числа, которые могут быть выражены как конечные суммы степеней 2 (включая отрицательные степени 2). Числа, такие как 0.5
, 0.25
, 0.75
(десятичные), будут представлены точно в бинарном формате с плавающей запятой, так как эти числа равны 2 ( 2^-1
, 2^-2
) или их суммам.
Между тем такое число, как десятичное 0.1
не может быть выражено конечной суммой степеней 2. Представление десятичного числа 0.1
в двоичном 0.1
с плавающей запятой имеет бесконечную длину. Это сразу же означает, что 0.1
не может быть представлен точно в конечном двоичном формате с плавающей запятой. Обратите внимание, что 0.1
имеет только одну десятичную цифру. Однако это число все еще не представимо. Это иллюстрирует тот факт, что выражение точности с плавающей запятой в терминах десятичных цифр не очень полезно.
Значения, такие как 0.85
и 0.65
из вашего примера, также не представляются, поэтому вы видите, что эти значения искажены после преобразования в конечный двоичный формат с плавающей запятой. Фактически, вы должны привыкнуть к тому, что большинство дробных десятичных чисел, с которыми вы столкнетесь в повседневной жизни, не будут отображаться точно в двоичных типах с плавающей запятой, независимо от того, насколько велики эти типы с плавающей точкой .
Единственный способ, с помощью которого я могу решить эту проблему, – передать характеристику и мантиссу функции отдельно и позволить ИТ работать над настройкой значений соответствующим образом.
Кроме того, если вы хотите больше точности,
http://www.drdobbs.com/cpp/fixed-point-arithmetic-types-for-c/184401992 – это статья, которую я знаю. Хотя это работает только для C ++. (Поиск эквивалентной реализации C).
Я пробовал это на VS2010,
#include void printfloat(float f) { printf("%f",f); } int main(int argc, char *argv[]) { float f = 0.24f; printfloat(f); return 0; } OUTPUT: 0.240000