×

面试必问:.NET 金额到底用 long 还是 decimal?90% 的人都用错了

独孤求败 独孤求败 发表于2026-02-25 10:23:14 浏览8 评论0

抢沙发发表评论

做电商、金融、支付、ERP,金额类型一错,全线埋雷。
在 .NET 里,金额用  long  还是  decimal ,不是习惯问题,是架构规范 + 安全底线。

这一篇讲清楚:什么时候用、为什么、怎么用才最稳。

 

一、先给结论(直接背)

- 系统内部计算、业务逻辑、展示:统一用 decimal
- 对接支付、第三方接口、存储分:建议用 long(以分为单位)
- 永远不要用 float / double 存金额

一句话口诀:
对内 decimal,对外 long;业务看元,交互看分。

 

二、为什么绝对不能用 float/double?

因为二进制浮点数不能精确表示 0.1、0.2 这类十进制小数。

你写:

csharp
 

double a = 0.1;
double b = 0.2;
if (a + b == 0.3) // 结果:false
 

实际结果是:

plaintext
 

0.30000000000000004
 

金融系统敢用浮点数,上线即事故。

 

三、decimal:.NET 专为钱设计的类型

 decimal  是十进制高精度类型,天生为金融、金额而生。

优点

- 精度极高,计算无误差
- 代码直观: 10.99m  就是 10 元 9 角 9 分
- 支持加减乘除、税率、折扣、分摊、利息
- 与数据库  decimal(18,2)  完美对应

适用场景

- 订单金额、优惠、运费、税费计算
- ERP、财务、进销存、工资、结算
- 所有业务层、领域层、DTO、展示

企业级写法

csharp
 

public class Order
{
    public int Id { get; set; }
    public decimal TotalAmount { get; set; }    // 总金额
    public decimal Discount { get; set; }       // 优惠
    public decimal PayAmount { get; set; }      // 实付
}
 

只要是你自己系统内部,无脑 decimal 绝不会错。

 

四、long:什么时候才用?(存分)

 long  是64 位整数,用来存分:

- 1 元 = 100 分 → 存 100
- 9.99 元 → 存 999

适用场景

- 对接微信支付、支付宝、云闪付
- 跨系统、跨语言接口(Java/Go 前端)
- 对精度极度敏感的结算、记账
- 历史老系统统一以分为单位

优点

- 完全无精度问题
- 传输、存储、序列化极稳
- 所有系统都能看懂

缺点

- 代码不直观:看到 39900 要反应一会是 399 元
- 业务计算要不停 ×100 ÷100

 

五、真实架构最佳实践(大厂标准)

1. 数据库

- 推荐:decimal(18,2)
- 特殊场景:bigint(存分)

2. 后端代码

- 实体、领域、服务层:decimal
- 对接支付工具:转 long(分)

3. 接口交互

- 内部接口:decimal
- 外部支付接口:long(分)

4. 工具类封装(必写)

csharp
 

public static class MoneyUtil
{
    // 元 → 分
    public static long YuanToFen(decimal yuan)
        => (long)(yuan * 100);

    // 分 → 元
    public static decimal FenToYuan(long fen)
        => fen / 100m;
}
 

 

六、一张表看懂怎么选

场景 类型 理由
业务逻辑、计算 decimal 直观、安全、无精度问题
展示、前端、报表 decimal 直接用,不用换算
订单、优惠、结算 decimal 金融级标准
对接支付第三方 long 行业统一规范(存分)
跨系统传输 long 无歧义、不丢精度
工资、财务、记账 decimal 合规、易审计

 

七、最终总结(面试必背)

1. 金额禁止 float/double
2. 内部业务全用 decimal
3. 支付交互统一用 long(分)
4. 封装工具类做元分互转

一句话:
业务看钱用 decimal,交互转账用 long。

在 .NET 里,把金额类型用对,
你就已经避开了 90% 的金融线上事

群贤毕至

访客