提问人:Will Felipe 提问时间:9/10/2021 最后编辑:Eric PostpischilWill Felipe 更新时间:9/14/2021 访问量:209
C - 浮点数不精确,如何锁定小数点后位置进行计算?
C - Float Imprecision, How to lock the decimal places for calculations?
问:
我当时在C语言中做了一个小程序来测试浮点数:程序本身很简单,我只想根据用户的输入,返回多少,他的数字有多少。Dollar(s), Quarter(s)... etc
//------------------------------> First Part: All the necessary Variables <-----------------------------
int main (void)
{
//Getting the user Input
float number = get_float("Number: ");
//Checking if is a positive number
if (number < 0)
{
printf("A positive number, Please: ");
}
//Declaring my Constant/Temporary variables.
float coinValues[] = {1.00, 0.25, 0.10, 0.5, 0.01};
char *coinNames[] = {"Dollar(s): ", "Quarter(s): ", "Dime(s): ", "Nickel(s): ", "Penny(ies): "};
int i = 0;
int tmp = 0;
//-----------------------------------> Second Part: The code Itself <-----------------------------------
//Checking/Printing the necessary coins.
while (number > 0)
{
//Until the loop stops, check if the number can be divided by the CoinValue.
if (number >= coinValues[i])
{
//Print the current Coin Name from the divided value.
printf("%s", coinNames[i]);
//Check if the Current Number still contains Coin Values inside of it, if True counts one in your "Coin Score".
while (number >= coinValues[i])
{
number -= coinValues[i];
tmp++;
}
//Print the Current "Coin Score", then resets TMP.
printf("%i\n", tmp);
tmp = 0;
}
else
{
//Updating the Coin value
i++;
}
}
}
只要我使用整数,我的程序运行得很好,但是当我将此代码转换为浮点数时,值开始在 Int 变量 tmp 中返回非预期结果。(Dime(s), Nickel(s), and Penny(ies))
像 2.6 这样的数字的预期结果是 2 美元、2 个季度和 1 角钱,但有时,程序不会使用一角钱,而是将它们全部跳过并使用镍进行操作,但是,困扰我的是程序总是返回没有任何值的 AWL=+,然后程序永远冻结。
考虑到我唯一的想法是我正在“遭受”浮动不精确,我不知道如何解决它,那么任何人都可以帮助我吗?
附言。在传递之前,程序需要始终返回每个硬币的最大值。
答:
4赞
Eric Postpischil
9/10/2021
#1
浮点运算旨在近似于实数算术。IEEE 754-2008 说:“浮点运算是实数算术的系统近似......”因此,无法在二进制浮点数中“锁定”十进制数字。它旨在用于需要近似值的地方,例如建模物理场。这甚至包括一些金融应用,例如期权评估。虽然浮点运算在某些情况下可用于精确计算,但这些需要特别小心,并且通常只在特殊情况下使用。
因此,关于如何锁定小数位的问题的答案是,使用二进制浮点没有很好的方法可以做到这一点。尝试这样做通常只会产生与整数算术相同的效果,但效率较低且代码难度更大。因此,请使用整数算术,并根据所需的最小货币单位(例如一分钱)缩放金额。
评论
double
260 / 100
60 / 25
0.1
0.01