所以我是大学第二学期的新生。我的老师希望我们编写一个将浮点数舍入到最近的百分之一的函数。他说我们需要将浮点数转换为整数数据类型,然后将其转换回浮点数。这就是他所说的。我花了至少5个小时尝试不同的方法来做到这一点。
到目前为止这是我的代码:
#include <stdio.h>
int rounding(int roundedNum);
int main()
{
float userNum,
rounded;
printf("\nThis program will round a number to the nearest hundredths\n");
printf("\nPlease enter the number you want rounded\n>");
scanf("%f", &userNum);
rounded = rounding (userNum);
printf("%f rounded is %f\n", userNum, rounded);
return 0;
}
int rounding(int roundedNum)
{
return roundedNum;
}
你的导师可能在想:
float RoundHundredth(float x)
{
// Scale the hundredths place to the integer place.
float y = x * 100;
// Add .5 to cause rounding when converting to an integer.
y += .5f;
// Convert to an integer, which truncates.
int n = y;
// Convert back to float, undo scaling, and return.
return n / 100.f;
}
这是一个有缺陷的解决方案,因为:
x * 100
中,结果通常不是x
的100倍。由于四舍五入,存在一个小错误。此错误会导致值越过圆形从一个方向变为另一个方向的点,因此它可能使答案错误。有一些技术可以避免这种错误,但它们对于入门课程来说太复杂了。trunc
的double
和truncf
的float
。round
为double
,roundf
为float
。如果你的C实现具有良好的格式化输入/输出例程,那么找到舍入到最接近的百位的浮点数值的简单方法是使用转换说明符snprintf
对其进行格式化(与%.2f
一样)。一个正确的C实现将数字转换为十进制,小数点后面有两位数,使用正确的舍入,避免上面提到的算术舍入错误。但是,您将获得字符串形式的数字。
以下是一些提示:
四种最常见的舍入方法是“远离零”和“银行家舍入(均匀)”。
用于舍入零的伪代码
编辑即使这是伪代码,我应该包括精度的计算,因为我们在这里处理浮点值。
// this code is fixed for 2 decimal places (n = 2) and
// an expected precision limit of 0.001 (m = 3)
// for any values of n and m, the first multiplicand is 10^(n+1)
// the first divisor is 10^(m + 1), and
// the final divisor is 10^(n)
double roundAwayFromZero(double value) {
boolean check to see if value is a negative number
add precision bumper of (1.0 / 10000) to "value" // 10000.0 is 10^4
multiply "value" by 1000.0 and cast to (int) // 1000.0 is 10^3
if boolean check is true, negate the integer to positive
add 5 to integer result, and divide by 10
if boolean check is true, negate the integer again
divide the integer by 100.0 and return as double // 100.0 is 10^2
ex: -123.456
true
-123.456 + (1.0 / 10000.0) => -123.4561
-123.4561 * 1000.0 => -123456.1 => -123456 as integer
true, so => -(-123456) => 123456
(123456 + 5) / 10 => 123461 / 10 => 12346
true, so => -(12346) => -12346
-12346 / 100.0 => -123.46 ===> return value
}
在您的初始问题中,您表达了对方向的渴望,而不是代码中的明确答案。这是模糊的,因为我可以设法做到它同时仍然有任何意义。我将留下“银行家的舍入”版本供您实施作为练习。
好的,我明白了!谢谢你的回答。
//function
float rounding(float roundedNumber)
{
roundedNumber = roundedNumber * 100.0f + 0.5f;
roundedNumber = (int) roundedNumber * 0.01f;
return roundedNumber;
}
所以,如果我输入56.12567作为roundNumber,它将乘以100,得到5612.567。从那里它将添加.5,这将决定它是否向上舍入。在这种情况下,确实如此。该数字将更改为5613.067。然后通过将其转换为int并将其乘以.01来截断它以获得小数。从那里它将值返回到main并打印出舍入的数字。很奇怪的舍入方式,但我猜你是如何在不使用舍入功能的情况下在C中完成的。
好吧,让我们考虑一下。有一点值得知道的是我们可以通过强制转换将float转换为整数:
float x = 5.4;
int y = (int) x;
//y is now equal to 5
当我们进行转换时,浮动被截断,这意味着无论其值如何(即它始终向0舍入),小数点之后的任何内容都将被删除。
因此,如果您考虑到这一点以及您关心百分之一的事实,您可以想象一种方法,包括在某种程度上操纵浮点数,这样当您将其转换为int时,您只会截断不是关心(即数字超过百分之一的地方)。乘法可能在这里很有用。