decimal是高精度十进制浮点数类型,专门用来做金钱,货币,财务计算解决float/double的精度丢失问题。
核心对比
| 类型 | 位数 | 本质 | 适用场景 |
|---|---|---|---|
float |
32 位 | 二进制浮点,有精度误差 | 科学计算、传感器、图形,不要算钱 |
double |
64 位 | 二进制浮点,依然有精度误差 | 绝大多数普通浮点运算,依然不适合金额 |
decimal |
128 位 | 十进制存储 | 💰货币、金额、财务、税率,要求精确小数 |
double/float是二进制存储小数,像0.1无法二进制精确表达,会出现计算误差。
decimal是按十进制存,0.1,0.01,0.05这类十进制小数不会丢精度。
语法要点
1.字面量必须加后缀m或M,不加m编译器会当成double,再转decimal
cs
decimal a = 0.1m; // ✅正确 decimal decimal b = 0.1; // ❌编译报错,0.1是double
2.范围:
- 范围:±7.9×10²⁸
- 精度:28‑29 位有效数字,小数位最多 28 位。
比 double 数值范围小,但是小数精度高得多。
示例:看 double 的坑,decimal 没问题
cs
// double 精度丢失
double d1 = 0.1 + 0.2;
Console.WriteLine(d1); //输出 0.30000000000000004
// decimal 精确
decimal dec1 = 0.1m + 0.2m;
Console.WriteLine(dec1); //输出 0.3
运算
支持 + - * / % 四则运算。
⚠️decimal 除法依然会产生除不尽,例如
1m / 3m,会保留 28 位小数,不会自动四舍五入,财务场景要手动Math.Round()。
cs
decimal res = Math.Round(1m / 3m,2); //保留2位小数,金额常用
和数据对应
- C#
decimal↔ SQL Serverdecimal / numeric
做财务系统,金额字段数据库用 decimal,C# 也用 decimal,不要用 double。
类型转换
cs
double x = 123.45;
decimal y = (decimal)x; // double转decimal
double z = (double)y; // decimal转double(会重新引入精度风险)
什么时候不用 decimal?
- 大数据量科学运算、坐标、传感器采样 → 用 double;decimal 运算速度比 double 慢不少;
- 不需要精确小数,追求性能就不用 decimal。