int*_*753 3 c floating-point printf
最初,我使用带有浮点数的 sprintf 始终使用以下代码保留 2 个小数位:
static void MyFunc(char* buffer, const float percentage)
{
sprintf(buffer, "%.2f", percentage);
}
Run Code Online (Sandbox Code Playgroud)
传递的百分比值之一是 0x419FFFFF 20(调试器视图),这将 20.00 打印到缓冲区中。
当不是整数时,我想显示 2 个小数位,例如
94.74 displayed as 94.74
94.7 displayed as 94.70
0 displayed as 0
5 displayed as 5
100 displayed as 100
Run Code Online (Sandbox Code Playgroud)
我目前正在使用以下代码:
static void MyFunc(char* buffer, const float percentage)
{
int fractional_part = ((percentage - (int)percentage) * 100);
if (0 == fractional_part)
{
sprintf(buffer, "%d", (int)percentage);
}
else
{
sprintf(buffer, "%.2f", percentage);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果通过 0x419FFFFF 20(调试器视图),小数部分计算为 99。我假设分数部分的总和最终为 (19.99 - 19) * 100 = 99。为什么第一个示例不将 19.99 打印到缓冲区中?
我的问题的正确解决方案是什么?
你的问题是近似问题。
假设百分比是 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
Run Code Online (Sandbox Code Playgroud)
如果您不同意printf的舍入策略,只需使用round()on(的副本)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
Run Code Online (Sandbox Code Playgroud)