C#中级、double和decimal有什么区别

在 C# 中,double 和 decimal 都是用来表示带小数的数值类型 ,但它们在内部表示、精度、性能和适用场景 上有本质区别。选择错误的类型可能导致严重精度问题(尤其在金融计算中)。


✅ 一句话总结区别

  • double :64 位双精度浮点数 ,基于 IEEE 754 标准 ,速度快、范围大,但有舍入误差 → 适合科学计算、图形、物理模拟。
  • decimal :128 位高精度十进制数 ,无二进制舍入误差 ,专为金融和货币计算设计 → 精确但速度慢、范围小。

🔍 详细对比表

特性 double decimal
关键字 double decimal
.NET 类型 System.Double System.Decimal
存储大小 64 位(8 字节) 128 位(16 字节)
精度 约 15-17 位有效数字 28-29 位有效数字
数值范围 ±5.0 × 10⁻³²⁴ 到 ±1.7 × 10³⁰⁸ ±1.0 × 10⁻²⁸ 到 ±7.9 × 10²⁸
内部表示 二进制浮点(以 2 为底) 十进制浮点(以 10 为底)
是否精确表示 0.1? ❌ 不能(有舍入误差) ✅ 能(精确)
性能 ⚡ 快(CPU 硬件直接支持) 🐢 慢(软件模拟)
默认字面量后缀 无(如 3.14 是 double) 需加 m 或 M(如 3.14m)

💥 关键区别:精度 vs 速度

❌ double 的经典陷阱:0.1 + 0.2 ≠ 0.3

复制代码
double a = 0.1;
double b = 0.2;
double sum = a + b;
Console.WriteLine(sum == 0.3);        // False!
Console.WriteLine(sum);               // 0.30000000000000004

原因:0.1 在二进制中是无限循环小数,无法精确表示。

✅ decimal 精确计算:

复制代码
decimal a = 0.1m;
decimal b = 0.2m;
decimal sum = a + b;
Console.WriteLine(sum == 0.3m);       // True!
Console.WriteLine(sum);               // 0.3

📌 字面量写法注意

复制代码
// double(默认)
double d1 = 123.45;    // OK
double d2 = 123.45d;   // 显式 d 后缀(可选)

// decimal(必须加 m/M)
decimal m1 = 123.45m;  // ✅ 正确
decimal m2 = 123.45;   // ❌ 编译错误!会先当作 double,再隐式转换(可能丢失精度)

⚠️ 永远不要写 decimal x = 0.1; ------ 这会先创建一个不精确的 double,再转成 decimal,错误已发生!


🧪 适用场景对比

✅ 使用 double 的场景:

  • 科学计算(物理、工程)
  • 图形渲染、游戏开发(坐标、速度)
  • 机器学习、统计分析
  • 对性能敏感、允许微小误差的场景

✅ 使用 decimal 的场景:

  • 金融、会计、货币计算(必须精确到分)
  • 税务计算
  • 任何需要十进制精确表示的业务逻辑
  • 用户输入的金额、价格等

💡 黄金法则 :
"涉及钱的地方,永远用 decimal!"


⚠️ 常见误区

❌ 误区 1:decimal 能表示任意大的数

虽然 decimal 精度高,但最大值只有约 7.9 × 10²⁸ ,远小于 double 的 10³⁰⁸。

如果需要超大数,考虑 BigInteger(整数)或自定义类型。

❌ 误区 2:decimal 性能差到不能用

虽然比 double 慢(约 10-20 倍),但在现代 CPU 上,一次 decimal 加法仍只需几十纳秒 。

对于金融系统(每秒几百笔交易),完全够用。

❌ 误区 3:可以用 double 存金额,只要四舍五入

即使显示时四舍五入,内部累积误差仍会导致对账不平 !

例如:1000 次 0.1 元累加,double 可能变成 99.99999999999999。


✅ 最佳实践建议

场景 推荐类型
金额、价格、利率 decimal
科学/工程计算 double
数据库字段 金额用 DECIMAL(p,s),科学数据用 FLOAT/DOUBLE
API 设计 金融接口参数/返回值用 decimal
常量定义 public const decimal TaxRate = 0.13m;

🧠 总结

问题 答案
哪个更精确? decimal(十进制无误差)
哪个更快? double(硬件加速)
存钱用哪个? 必须用 decimal
0.1 能精确表示吗? double ❌,decimal ✅
字面量怎么写? double: 3.14;decimal: 3.14m

💡 记住 :
"double 为速度而生,decimal 为正确而战。"

在金融世界里,一分钱都不能错 ------这就是 decimal 的存在意义。

问题

double和float有什么区别

double占用64位内存,而float占用32位

什么是NaN

NaN表示非数字,它是double或float可以具有特殊值,0除以0的结果

相关推荐
Wang's Blog4 分钟前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧30 分钟前
C#:输入的字符串格式不正确
c#
程序喵大人2 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)2 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的3 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质3 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄6234 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_962885724 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python
临床数据科学和人工智能兴趣组5 小时前
在R语言的生态系统中,字符串处理一直是一个重要且复杂的任务
开发语言·正则表达式·r语言·r语言-4.2.1
蜗牛互联网5 小时前
Python调用Gemini Structured Outputs实现工单路由门禁
java·开发语言·人工智能·python