将 float 转换为 int 会改变值
Conversion of float to int changes the value
我看过this question,好像不是同一种情况。
我正在编写的支票登记程序中有一个函数,它从用户那里读取美元金额,验证它不是用小数美分输入的,并与用户核对输入是否正确。不过,我得到的是,在将输入的浮点值乘以 100 并用 (int)
截断后,该值发生了变化。例如,如果我输入 1118.58,我可以(通过调试 printf
语句)验证 1118.58 是否被正确扫描并分配给 amt
,以及我的 while
条件 (int)100 * amt == 100 * amt
是否正确测试为 TRUE
,但在转换为整数后,整数值存储为 111857。更令人费解的是,并不是每个值都会发生这种情况(尽管我的测试进展顺利,这是第一个条目我见过这样的变化)。
我在 Kubuntu 14.04 64 位上使用 gcc,在我的编译命令中使用 C99 标准设置。
这是出现问题的函数(假设您没有 want/need 查看完整程序的 1300 行)。注意:为了方便起见,我在头文件中定义了布尔值和运算符——我最近发现有一种标准方法可以做到这一点,但还没有转换我的头文件。
int get_amt (void)
{
float amt;
int scanned, i_amt;
int success = FALSE;
char yn = '[=10=]';
while (NOT success)
{
scanned = scanf("%f%*c", &amt);
/* validate and verify amount */
if (scanned >= 1 AND (int)100*amt == 100*amt AND amt <= 100000)
{
i_amt = (int)(100 * amt);
printf("\n amt = %4.2f i_amt = %i", amt, i_amt);
printf("\nYou entered $%i.%.2i -- Correct (Y/n)?", i_amt/100, i_amt%100);
scanf("%c%*c", &yn);
if (yn == '[=10=]' OR yn == 'Y' OR yn == 'y')
success = TRUE;
}
}
return (i_amt);
}
下面是带有调试打印语句的输出示例:
Enter deposit amount (dollars and cents): $ 1118.58
amt = 1118.58 i_amt = 111857
You entered 18.57 -- Correct (Y/n)?
为什么会发生这种情况,我该如何解决?
在下面的评论中讨论后,我已经将函数转换为使用整数,因此不存在浮点精度问题(我没有真正考虑标准浮点数在 64 位上的精度有多低OS 和编译器)。这是更新后的版本,因为没有浮点数,所以不会失败:
int get_amt (void)
{
int scanned, amt1, amt2;
int success = FALSE;
char yn = '[=12=]';
while (NOT success)
{
scanned = scanf("%i.%i%*c", &amt1, &amt2);
/* validate and verify amount */
if (scanned >= 1)
{
printf("\nYou entered $%i.%.2i -- Correct (Y/n)?", amt1, amt2);
scanf("%c%*c", &yn);
if (yn == '[=12=]' OR yn == 'Y' OR yn == 'y')
success = TRUE;
}
}
return (100*amt1 + amt2);
}
正如@MitchWheat 在上面的评论中提到的那样,当您打印出 float
时,它很可能会四舍五入,而当您计算 int
时,它只是截断.使用 round
函数解决这个问题。即,i_amt = round(100 * amt);
将以与 float
相同的方式对数字进行四舍五入。
我看过this question,好像不是同一种情况。
我正在编写的支票登记程序中有一个函数,它从用户那里读取美元金额,验证它不是用小数美分输入的,并与用户核对输入是否正确。不过,我得到的是,在将输入的浮点值乘以 100 并用 (int)
截断后,该值发生了变化。例如,如果我输入 1118.58,我可以(通过调试 printf
语句)验证 1118.58 是否被正确扫描并分配给 amt
,以及我的 while
条件 (int)100 * amt == 100 * amt
是否正确测试为 TRUE
,但在转换为整数后,整数值存储为 111857。更令人费解的是,并不是每个值都会发生这种情况(尽管我的测试进展顺利,这是第一个条目我见过这样的变化)。
我在 Kubuntu 14.04 64 位上使用 gcc,在我的编译命令中使用 C99 标准设置。 这是出现问题的函数(假设您没有 want/need 查看完整程序的 1300 行)。注意:为了方便起见,我在头文件中定义了布尔值和运算符——我最近发现有一种标准方法可以做到这一点,但还没有转换我的头文件。
int get_amt (void)
{
float amt;
int scanned, i_amt;
int success = FALSE;
char yn = '[=10=]';
while (NOT success)
{
scanned = scanf("%f%*c", &amt);
/* validate and verify amount */
if (scanned >= 1 AND (int)100*amt == 100*amt AND amt <= 100000)
{
i_amt = (int)(100 * amt);
printf("\n amt = %4.2f i_amt = %i", amt, i_amt);
printf("\nYou entered $%i.%.2i -- Correct (Y/n)?", i_amt/100, i_amt%100);
scanf("%c%*c", &yn);
if (yn == '[=10=]' OR yn == 'Y' OR yn == 'y')
success = TRUE;
}
}
return (i_amt);
}
下面是带有调试打印语句的输出示例:
Enter deposit amount (dollars and cents): $ 1118.58
amt = 1118.58 i_amt = 111857
You entered 18.57 -- Correct (Y/n)?
为什么会发生这种情况,我该如何解决?
在下面的评论中讨论后,我已经将函数转换为使用整数,因此不存在浮点精度问题(我没有真正考虑标准浮点数在 64 位上的精度有多低OS 和编译器)。这是更新后的版本,因为没有浮点数,所以不会失败:
int get_amt (void)
{
int scanned, amt1, amt2;
int success = FALSE;
char yn = '[=12=]';
while (NOT success)
{
scanned = scanf("%i.%i%*c", &amt1, &amt2);
/* validate and verify amount */
if (scanned >= 1)
{
printf("\nYou entered $%i.%.2i -- Correct (Y/n)?", amt1, amt2);
scanf("%c%*c", &yn);
if (yn == '[=12=]' OR yn == 'Y' OR yn == 'y')
success = TRUE;
}
}
return (100*amt1 + amt2);
}
正如@MitchWheat 在上面的评论中提到的那样,当您打印出 float
时,它很可能会四舍五入,而当您计算 int
时,它只是截断.使用 round
函数解决这个问题。即,i_amt = round(100 * amt);
将以与 float
相同的方式对数字进行四舍五入。