我有两个值,我想像这样四舍五入。在 C# 中,我如何才能比输入的小数点少一位?
100.67 -> 100.7 -- 向上
100.67 -> 100.6 -- 向下
50.563 -> 50.57 -- 向上
50.563 -> 50.56 -- 向下
我试过这个代码块,但它没有像我想要的那样工作。我不想给出四舍五入的精度。无论十进制值是多少,我都需要将其向上或向下舍入。
public double RoundDown(double number, int decimalPlaces)
{
return Math.Floor(number * Math.Pow(10, decimalPlaces)) / Math.Pow(10, decimalPlaces);
}
public double RoundUp(double number, int decimalPlaces)
{
return Math.Ceiling(number * Math.Pow(10, decimalPlaces)) / Math.Pow(10, decimalPlaces);
}
为了术语,我想在这里更严格地定义“舍入”。 “将 x 向上舍入到 n 位小数”将称为“将 x 向上舍入到 n 位的精度”,更具体地说是“找到大于或等于 x 且最多使用小数点后 n 位的最接近数字” “至多”部分实际上很重要,因为“将 10.9991 舍入到 3 位精度”将是“11”。
您的问题要求一种四舍五入到“比输入少一位小数”的方法,特别是不需要告诉该方法输出应该具有的精度。其中存在一个隐藏的问题:根据 IEEE 754.
使用浮点表示法的数字用于存储数字的小数位数可能不是您自然期望的。虽然该标准做得非常好,但将带有 2 个小数位的数字相加可能会很快得到一个带有“无限”小数位的数字。考虑这个例子:
var x = 0.0002f;
var x5 = 5 * x;
得知
x5
不是 0.001
而是 0.0009999999
,您可能会感到惊讶。在这种情况下,从 double
转到 float
会有所帮助,但最终 double
会遇到同样的问题,只是因为值不同。
那么,您对
RoundUp(x5)
的期待是什么?如果值为0.001
,您的期望将是0.01
。但是 0.0009999999
代表一个虚构的 0.0009...
的小数位数是多少?即使我们为了论证说0.0009999999
正好等于0.00099999990
,从而得出结论它有10位小数,那么它四舍五入到9位的精度意味着在最后滚动九位直到我们到达0.001
,而不是0.01
.
因此,不可能通过算法安全地确定给定的以 10 为底的浮点数的“小数位数”。因此,您需要为任何函数提供所需的精度,这将引导您找到已有的代码。