当前位置: 首页 > news >正文

C# 浮点数与定点数详细解析

C# 浮点数与定点数详细解析

在 C# 中,数值类型分为整数、浮点数和定点数。浮点数和定点数在计算机内部的表示方式不同,导致精度和使用场景也不同。


1️⃣ 浮点数(float / double)

1.1 表示方法

浮点数采用 IEEE 754 二进制科学计数法

值 = (-1)^符号位 × 1.尾数 × 2^(指数 - 偏移量)
  • 符号位(Sign bit):1 位,表示正负
  • 指数位(Exponent):控制缩放大小
  • 尾数位(Mantissa/Fraction):存储有效数字

例子:

类型位数符号位指数位尾数位
float321823
double6411152

浮点数能表示的范围很大,但精度有限,尤其是某些十进制小数在二进制里无法精确表示。


1.2 小数部分的二进制表示

浮点数小数部分用 2 的负次方表示:

二进制位十进制值
0.1₂0.5
0.01₂0.25
0.001₂0.125
0.0001₂0.0625
0.00001₂0.03125

每一位累加得到的值逼近原来的十进制小数,但不一定能精确等于


1.3 为什么 0.1 在二进制里不能精确表示?

  • 十进制 0.1 = 1/10
  • 二进制只能用 2 的负次方表示分数
  • 10 不是 2 的倍数 → 二进制表示是无限循环小数
0.1 十进制 = 0.00011001100110011...₂(无限循环)

累加前几位逼近 0.1:

二进制位十进制值累加
2⁻⁴0.06250.0625
2⁻⁵0.031250.09375
2⁻⁸0.003906250.09765625
2⁻⁹0.0019531250.099609375

计算机只能存储有限位数 → 截断 → 得到近似值 → 浮点数运算可能有微小误差。


1.4 示例:0.1 + 0.2

Console.WriteLine(0.1 + 0.2 == 0.3);  // false
Console.WriteLine(0.1 + 0.2);         // 0.30000000000000004

原因:

  • 0.1 和 0.2 在二进制里都是无限循环小数
  • 存储时截断 → 相加结果只是接近 0.3
  • == 比较是精确位比较 → 返回 false
✅ 正确做法
  1. 近似比较(epsilon)
double a = 0.1 + 0.2;
double b = 0.3;
double epsilon = 1e-10;
Console.WriteLine(Math.Abs(a - b) < epsilon); // True
  1. 使用 decimal(高精度定点数)
decimal a = 0.1m + 0.2m;
decimal b = 0.3m;
Console.WriteLine(a == b); // True
  1. 仅用于显示匹配时,转字符串
double a = 0.1 + 0.2;
Console.WriteLine(a.ToString("F1") == "0.3"); // True

2️⃣ 定点数(decimal)

2.1 表示方法

  • 总共 128 位存储

    • 96 位存整数部分(有效数字)
    • 16 位存小数位精度(scale,表示小数点位置)
  • 十进制方式存储 → 能精确表示 0.1、0.2 等十进制小数

2.2 特点

  • 高精度、适合金融、货币计算
  • 范围比 double 小,但计算精确
  • 不会出现 0.1+0.2==0.3 这种浮点误差

2.3 示例

decimal price1 = 0.1m;
decimal price2 = 0.2m;
Console.WriteLine(price1 + price2 == 0.3m); // True

3️⃣ 总结对比表

特性float / double(浮点数)decimal(定点数)
存储方式二进制科学计数法十进制定点数
精度有误差高精度
范围较小
适用场景科学计算、物理模拟金融、货币、账务

4️⃣ 小结

  • 浮点数有范围大、速度快的优点,但十进制小数可能无法精确表示
  • decimal 能精确表示十进制小数,适合对精度要求高的场景
  • 1/3、π 在十进制中可能无限循环
  • 0.1、0.2 在二进制中可能无限循环 → 浮点数加法出现微小误差
  • 浮点数判断相等最好 用 epsilon 或 decimal
http://www.dtcms.com/a/344012.html

相关文章:

  • 邀请函 | 2025达索系统高峰论坛,跨界融合定义未来制造
  • SamOutVXP:革命性轻量级语言模型,突破传统推理限制
  • 不同类型代理 IP 在爬虫场景下的表现对比
  • 苹果紧急修复ImageIO零日漏洞CVE-2025-43300,已被在野利用
  • 开源AI编程工具Kilo Code的深度分析:与Cline和Roo Code的全面对比
  • QT之QSS常用颜色总结
  • 【黑客技术零基础入门】计算机网络---子网划分、子网掩码和网关(非常详细)零基础入门到精通,收藏这一篇就够了
  • 【每天一个知识点】AIOps 与自动化管理
  • 二、高可用架构(Nginx + Keepalived + MySQL 主从)
  • 集成算法(聚类)
  • Vue生命周期以及自定义钩子和路由
  • Manus AI 与多语言手写识别技术全解析
  • c++最新进展
  • linux下top命令分析内存不足vs负载过高
  • MeterSphere接口自动化多场景批量运行复制引用
  • 疯狂星期四文案网第47天运营日记
  • 云市场周报 (2025.08.22):阿里云RDS降价、腾讯云Serverless容器新品发布
  • Adobe Photoshop 2025 版本介绍与使用指南
  • AE下载安装教程(附安装包)Adobe Media Encoder超详细图文安装教程
  • Azure TTS Importer:一键导入,将微软TTS语音接入你的阅读软件!
  • 开发避坑指南(30):Vue3 表格动态增加删除行解决方案
  • 数据库备份sql文件过大,phpAdmin无法执行Sql
  • 深入理解Spring事务传播行为:原理、应用与实践
  • Vue Teleport 原理解析与React Portal、 Fragment 组件
  • 高德地图自定义marker,点击、悬停显示信息框
  • 智能合约漏洞检测技术综述:守护区块链世界的“自动售货机”
  • syn和quote的简单使用——生成结构体
  • Java基础 8.22
  • 在自动驾驶中ESKF实现GINS时,是否将重力g作为变量考虑进去的目的是什么?
  • 从Transformer到扩散模型:解锁大模型背后的技术魔法