传送门
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
// 先看看double类型 通过Math.Round取两位小数得到什么
Console.WriteLine( Math.Round(2.345d, 2)); //2.35
// 再看看decimal类型通过Math.Round取两位小数得到什么
Console.WriteLine( Math.Round(2.345m, 2)); //2.34
// 对decimal类型,采用了银行家舍入算法:四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一
Console.WriteLine( Math.Round(2.3451m, 2)); //2.35 五后非空就进一
Console.WriteLine( Math.Round(2.345m, 2)); //2.34 五后为空看奇偶,五前为偶应舍去
Console.WriteLine( Math.Round(2.335m, 2)); //2.34 五前为奇要进一
// 而对于double类型,没那么多讲究,直接满五进一
Console.WriteLine( Math.Round(2.3451d, 2)); //2.35
Console.WriteLine( Math.Round(2.345d, 2)); //2.35
Console.WriteLine( Math.Round(2.335d, 2)); //2.34
Console.WriteLine( Math.Round(2.334d, 2)); //2.33
// 再来看一个容易疏忽的格式化问题,不管是double还是decimal类型,ToString("0.00")都会做四舍五入
Console.WriteLine( 2.345d.ToString("0.00")); //2.35
Console.WriteLine( 2.345m.ToString("0.00")); //2.35
// 对于decimal类型
Console.WriteLine( Math.Round(2.345m, 2, MidpointRounding.AwayFromZero)); //2.35
Console.WriteLine( Math.Round(2.345m, 2, MidpointRounding.ToEven)); //2.34
Console.WriteLine( Math.Round(2.375m, 2, MidpointRounding.AwayFromZero)); //2.38
Console.WriteLine( Math.Round(2.375m, 2, MidpointRounding.ToEven)); //2.38
// 不四舍五入,而切掉后面的小数位,
var pre = 1.4665m;
var cut = pre - (pre % 0.01M);
Console.WriteLine(cut.ToString("0.00")); //1.46
cut = pre - (pre % 0.001M);
Console.WriteLine(cut.ToString("0.000")); //1.466
// 用Math库函数,先扩大再缩小,这种情况需要注意,小数位数很大的情况下的精度问题
decimal step = (decimal)Math.Pow(10, 2);
decimal tmp = Math.Truncate(step * 1.5351m);
Console.WriteLine(tmp / step);
}
}