在c#
中回合100.11到100.15和100.16到100.20我尝试了所有这些东西,但这些都没有帮助我。
Math.Round(100.11, 2,MidpointRounding.AwayFromZero); //gives 100.11
Math.Round(100.11, 2,MidpointRounding.ToEven);//gives 100.11
Math.Round((Decimal)100.11, 2)//gives 100.11
(100.11).ToString("N2"); //gives "100.11"
Math.Floor(100.11);// gives 100.0
(100.11).ToString("#.##");//gives "100.11"
Math.Truncate(100.11);// gives 100.0
Math.Ceiling(100.11);//gives 101.0
(100.11).ToString("F4");// gives "100.1100"
答案 0 :(得分:8)
这应该给出期望的结果
decimal Round (decimal value, decimal granularity)
{
return Math.Ceiling(value/granularity+0.5M)*granularity;
}
// myResult = Round(110.11,0.05);
// myResult = Round(110.16,0.05);
通常:将粒度设置为您希望舍入值的方式的十进制值,例如: 0.1
将向上舍入到最接近的小数。您还可以应用0.25
之类的奇数值,这些值将舍入为0.25
,0.50
,0.75
和1.0
。
删除+0.5M
只会舍入到最接近的值(而不是向上舍入)。
答案 1 :(得分:4)
问题严重需要样本;如果向上舍入,则delta等于 1/20 ,即:
100.10 -> 100.10
100.11 -> 100.15 // <- round UP; that's why 100.15 not 100.10
...
100.15 -> 100.15
100.16 -> 100.20
...
100.20 -> 100.20
100.21 -> 100.25
你可以使用这个简单的代码
Double value = 100.11;
Double result = Math.Round(value * 20.0 + 0.49999999) / 20.0;
答案 2 :(得分:0)
Alzaimar提供的答案非常有趣和有用。但请注意,在处理float或double值时它并不完全有用。
一般情况下,您可以使用类似的方法来干净地使用#34; Granularize&#34;浮点值:
public double Granularize(double value, double granularity)
{
var precision = (Decimal.GetBits((decimal)value)[3] >> 16) & 0x000000FF;
return Math.Round(Math.Round(value / granularity, 0) * granularity, precision);
}
显然,你可以使用相同的基本前提推导出float / double的上限方法。
我只想指出,使用粒度(如0.1d)不会给出正确的粒化结果,而不会舍入到粒度的精度。你有时会在小数点后13位左右出现虚假的不精确度。