你可以在C#中将一个double四舍五入或舍去小数点输入值少一位小数位。

huangapple go评论137阅读模式
英文:

How can I round up or down a double to one less decimal place than the input has in C#?

问题

I have two values and I want to round them like this. How can I do this for one less decimal place than the input has with math methods in C#?

100.67 -> 100.7 -- up

100.67 -> 100.6 -- down

50.563 -> 50.57 -- up

50.563 -> 50.56 -- down

I tried this code block, but it didn't work like I want. I don't want to give a precision for rounding. Whatever the decimal value is, I need to round it up or down.

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);
}
英文:

I have two values and I want to round them like this. How can I do this for one less decimal place than the input has with math methods in C#?

100.67 -> 100.7 -- up

100.67 -> 100.6 -- down

50.563 -> 50.57 -- up

50.563 -> 50.56 -- down

I tried this code block, but it didn't work like I want. I don't want to give a precision for rounding. Whatever the decimal value is, I need to round it up or down.

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);
}

答案1

得分: 3

为了术语的准确性,我想更严格地定义一下“舍入”。将“将 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。从float转到double在这种情况下会有所帮助,但最终double也会遇到相同的问题,只是针对不同的值。

那么,您对RoundUp(x5)的期望是什么?如果值为0.001,您的期望将是0.01。但用于表示虚构的0.0009...0.0009999999具有多少小数位呢?即使我们为了争论的缘故说0.0009999999恰好等于0.00099999990,从而得出它具有 10 位小数位的结论,那么它向上舍入到 9 位精度意味着在最后的九位上滚动直到到达0.001,而不是0.01

因此,无法通过算法安全地确定给定浮点数在 10 进制中具有多少小数位。因此,您需要向任何函数提供所需的精度,这将引导您到已经存在的代码。

英文:

For the sake of terminology, I want to define "rounding" a bit more rigorous here. "Rounding up x to n decimal places" will be called "Rounding up x to a precision of n places", and will more specifically mean "Finding the closest number greater than or equal to x that uses at most n places behind the decimal point." The "at most" part is actually important, because "rounding 10.9991 up to a precision of 3 places" will be "11".

Your question asks for a method that rounds to "one less decimal place than the input", specifically without the necessity to tell that method the precision the output is supposed to have. Therein lies a hidden problem: numbers using floating point representation according to IEEE 754.

The number of decimal places used to store a number may not be what you would naturally expect. While the standard does a really good job, adding numbers with 2 decimal places may quickly result in a number with "infinite" decimal places. Consider this example:

var x = 0.0002f;
var x5 = 5 * x;

It may surprise you to learn that x5 is not 0.001 but 0.0009999999. Going to double from float helps in this case, but ultimately double will suffer from the same problem, just for different values.

So, what is your expectation for RoundUp(x5)? If the value was 0.001, your expectation would be 0.01. But what is the number of decimal places for 0.0009999999 which represents a fictional 0.0009... with infinite decimal places? And even if we say 0.0009999999 was exactly equal to 0.00099999990 for the sake of argument, and thereby conclude it has 10 decimal places, then it rounding up to a precision of 9 places means rolling over the nines at the end until we arrive at 0.001, not 0.01.

Therefore, it is impossible to algorithmically safely determine "how many decimal places" a given floating point number has in base 10. Therefore you need to provide the desired precision to any function, which will lead you to the code you already have.

huangapple
  • 本文由 发表于 2023年4月17日 16:31:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76033141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定