你的问题是近似问题。
假设百分比为 19.999。然后fractional_part
是 99,浮点分支将被调用。
但是用两位小数打印 19.999 会将其四舍五入为 20.00,这就是打印的内容。
您始终可以使用浮点分支,以获得一致的结果,然后在 '.' 处截断。如果它以 '.00' 出现。否则,您可能会冒着您的测试和printf
的内部结构在某个时候发生冲突的风险。
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
float percentage = 19.999;
char buffer[50];
for (percentage = 19.990; percentage < 20.001; percentage += 0.001)
{
sprintf(buffer, "%.2f", percentage);
char *p = strstr(buffer, ".00");
if (p) *p = 0x0;
printf("%.3f rendered as %.2f and becomes %s\n", percentage, percentage, buffer);
}
return 0;
}
19.990 rendered as 19.99 and becomes 19.99
19.991 rendered as 19.99 and becomes 19.99
19.992 rendered as 19.99 and becomes 19.99
19.993 rendered as 19.99 and becomes 19.99
19.994 rendered as 19.99 and becomes 19.99
19.995 rendered as 19.99 and becomes 19.99
19.996 rendered as 20.00 and becomes 20
19.997 rendered as 20.00 and becomes 20
19.998 rendered as 20.00 and becomes 20
19.999 rendered as 20.00 and becomes 20
20.000 rendered as 20.00 and becomes 20
20.001 rendered as 20.00 and becomes 20
如果您不同意printf
's 的舍入策略,请使用round()
on (a copy of)percentage
并强制使用您自己的。或者,您也可以sprintf()
使用三个数字,然后擦除第三个数字。
在您的特定情况下(请注意我的系统(Linux x86_64)如何呈现 0x419FFFFF):
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int main(int argc, char **argv)
{
float percentage = 3.1415;
char buffer[50];
((uint32_t *)(&percentage))[0] = 0x419FFFFF;
sprintf(buffer, "%.2f", percentage);
char *p = strstr(buffer, ".00");
if (p) *p = 0x0;
printf("%.15f rendered as %.2f and becomes %s\n", percentage, percentage, buffer);
return 0;
}
19.999998092651367 rendered as 20.00 and becomes 20