我有一个十进制数,可能像以下这样:
189.182
我想将其向上舍入到2位小数,因此输出应该是以下内容:
189.19
在Math类或其他地方是否有内置的功能可以实现此功能? 我知道ceiling函数存在,但它似乎不能实现我的要求- 它会四舍五入到最近的整数,所以在这种情况下只是'189'。
乘以100,向上取整,再除以100可以得到我认为你要求的结果。
public static double RoundUp(double input, int places)
{
double multiplier = Math.Pow(10, Convert.ToDouble(places));
return Math.Ceiling(input * multiplier) / multiplier;
}
用法示例:
RoundUp(189.182, 2);
这个方法通过将小数点向右移动两位(使其位于最后一个8的右侧),然后执行上取整操作,最后将小数点移回到原来的位置。
189.182
这样的数字,你应该是相当安全的。也许应该转换为十进制? - Simon_Weaver您可以使用:
decimal n = 189.182M;
n = System.Math.Ceiling (n * 100) / 100;
这里可以找到有关各种舍入函数的解释。
请注意,像这样的公式仍受限于double
类型的有限精度,如果您使用的是该类型(虽然您的问题陈述了十进制数,但您可能只是指具有分数部分的浮点值而不是具体类型)。
例如:
double n = 283.79;
n = System.Math.Ceiling (n * 100);
实际上将会返回28380
,而不是你预期的283.79
(a)。
如果你想在所有情况下得到准确的结果,你一定要使用decimal
类型。
(a)这是因为283.79
的最准确的IEEE754双精度表示实际上是::
283.790000000000020463630789891
那个额外的(尽管微不足道的)小数部分超过了.79
,它将被上取整,这意味着它会给你一个比你预期的值更高的结果。
1. MidpointRounding.ToNegativeInfinity
2. MidpointRounding.ToPositiveInfinity
3. MidpointRounding.ToZero
MidpointRounding.ToPositiveInfinity
,这将始终将数字向上舍入。请注意,仅当数字不为负数时才有效。请参见下表中的示例。
原始数字 | ToNegativeInfinity | ToPositiveInfinity | ToZero |
---|---|---|---|
3.55 | 3.5 | 3.6 | 3.5 |
2.83 | 2.8 | 2.9 | 2.8 |
2.54 | 2.5 | 2.6 | 2.5 |
2.16 | 2.1 | 2.2 | 2.1 |
-2.16 | -2.2 | -2.1 | -2.1 |
-2.54 | -2.6 | -2.5 | -2.5 |
-2.83 | -2.9 | -2.8 | -2.8 |
-3.55 | -3.6 | -3.5 | -3.5 |
// function explained: Math.Round(number, amount of decimals, MidpointRounding);
decimal number = 189.182m;
number = Math.Round(number, 2, MidpointRounding.ToPositiveInfinity);
// result: number = 189.19
var numberToBeRound1 = 4.125;
var numberToBeRound2 = 4.175;
var numberToBeRound3 = 4.631;
var numberToBeRound4 = 4.638;
var numberOfDecimalPlaces = 2;
var multiplier = Math.Pow(10, numberOfDecimalPlaces);
//To Round Up => 4.13
var roundedUpNumber = Math.Ceiling(numberToBeRound1 * multiplier) / multiplier;
//To Round Down => 4.12
var roundedDownNumber = Math.Floor(numberToBeRound1 * multiplier) / multiplier;
//To Round To Even => 4.12
var roundedDownToEvenNumber = Math.Round(numberToBeRound1, numberOfDecimalPlaces, MidpointRounding.ToEven);
//To Round To Even => 4.18
var roundedUpToEvenNumber = Math.Round(numberToBeRound2, numberOfDecimalPlaces, MidpointRounding.ToEven);
//To Round To Away From Zero => 4.63
var roundedDownToAwayFromZero = Math.Round(numberToBeRound3, numberOfDecimalPlaces, MidpointRounding.AwayFromZero);
//To Round To Away From Zero => 4.64
var roundedUpToAwayFromZero2 = Math.Round(numberToBeRound4, numberOfDecimalPlaces, MidpointRounding.AwayFromZero);
Math.Round(number, decimalPlaces, MidpointRounding.AwayFromZero);
- Csaba Toth0.01 * ceil(100 * 189.182)
public static decimal RoundUp(decimal input, int places)
{
decimal multiplier = (decimal)Math.Pow(10, places);
return decimal.Ceiling(input * multiplier) / multiplier;
}
Math.Round()
。decimal RoundUp(decimal n, int decimals)
{
n += decimal.Parse($"1e-{decimals}", System.Globalization.NumberStyles.AllowExponent) / 2;
n -= 1e-28m;
return Math.Round(n, decimals);
}
decimal RoundDown(decimal n, int decimals)
{
n -= decimal.Parse($"1e-{decimals}", System.Globalization.NumberStyles.AllowExponent) / 2;
n += 1e-28m;
return Math.Round(n, decimals);
}
它的优点是不使用Math.Pow()
,后者使用double
,因此可能会导致不可预测的舍入误差。
这个解决方案基本上使用了中点舍入可以通过稍微增加/减少数字来转换为上下舍入的事实:
Math.Round(3.04m, 1)
是 3.0
- 不是我们想要的0.04(9)
Math.Round(3.0899999999999999999999999999m, 1)
是 3.1
- 成功了!减去1e-28m
(= 0.0000000000000000000000000001
)很重要,因为我们希望能将3.0000000000000000000000000001
四舍五入成4
,但3.0000000000000000000000000000
应该保持为3
。
// Double will return the wrong value for some cases. eg: 160.80
public static decimal RoundUp(decimal input, int places)
{
decimal multiplier = Convert.ToDecimal(Math.Pow(10, Convert.ToDouble(places)));
return Math.Ceiling(input * multiplier) / multiplier;
}
Math.Round(price, 2, MidpointRounding.AwayFromZero);
`public static decimal RoundUp(decimal input, int places) { if (places < 0) return input; decimal multiplier = 1; for (int i = 0; i < places; ++i) multiplier *= 10; return (Math.Ceiling(input * multiplier) / multiplier); }`
- Steve Hibbert