C# 浮点数与定点数的原理与用法对比

 更新时间:2025年08月25日 10:09:33   作者:星夜泊客  
浮点数和定点数在内部的表示方式不同,导致它们的 精度、范围、性能、使用场景 都有明显区别,本文将详细剖析两者的原理与对比,感兴趣的朋友跟随小编一起看看吧

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

在 C# 中,数值类型主要分为:

  • 整数型int, long 等)
  • 浮点型float, double
  • 定点型decimal

浮点数和定点数在内部的表示方式不同,导致它们的 精度、范围、性能、使用场景 都有明显区别。本文将详细剖析两者的原理与对比。

1️⃣ 浮点数(float / double)

1.1 表示方法(IEEE 754)

浮点数采用 二进制科学计数法 存储:

值 = (-1)^符号位 × 1.尾数 × 2^(指数 - 偏移量)
  • 符号位:1 位,表示正负
  • 指数位:控制缩放大小
  • 尾数位:存储有效数字
类型位数符号位指数位尾数位
float321823
double6411152

👉 范围极大,但精度有限。某些小数在二进制中无法精确表示。

1.2 小数的二进制表示

浮点数小数用 2 的负次方来组合:

0.101₂ = 2⁻¹ + 2⁻³ = 0.5 + 0.125 = 0.625

但像 0.1 这样的十进制分数,在二进制中是无限循环小数:

0.1₁₀ = 0.0001100110011...₂

只能近似存储 → 运算会出现误差。

1.3 常见误差示例

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

原因:二进制截断 → 加法结果不是精确的 0.3。

1.4 特殊值

浮点数里其实还藏着几个特别的数,它们在实际开发里经常会遇到:

  • 正无穷 / 负无穷
  • 当结果太大,已经超过浮点数能表示的范围时,就会变成无穷大:
  • double.PositiveInfinity → 正无穷
  • double.NegativeInfinity → 负无穷
  • NaN(Not a Number,意思是“不是一个数”)
  • 一些数学上不合法的运算会得到 NaN,比如:
  • Console.WriteLine(double.NaN == double.NaN); // false
    
  • 0.0 / 0.0
  • Math.Sqrt(-1)
  • 特别注意:NaN 和任何值比较(甚至跟自己比)都会是 false
  • +0 和 -0
  • 浮点数里其实区分正零和负零,不过在大多数运算里,它们没区别:
  • +0 == -0 结果是 true
  • 但在某些场景(比如除法)下会有区别:
  • Console.WriteLine(1.0 / +0); // Infinity
    Console.WriteLine(1.0 / -0); // -Infinity
    

1.5 浮点数比较正确姿势

  1. 近似比较(epsilon 容差)
bool IsEqual(double a, double b, double eps = 1e-10)
    => Math.Abs(a - b) < eps;
  1. 游戏开发常见做法(Godot / Unity)
Mathf.Approximately(a, b);      // Unity
Mathf.IsEqualApprox(a, b);      // Godot
  1. 避免直接用 ==
    除非数据本身是整数运算得来的,或者特别确定是完全相等。

2️⃣ 定点数(decimal)

2.1 表示方法

  • 总共 128 位存储
    • 96 位存有效数字
    • 16 位存小数位精度(scale,小数点位置)
  • 十进制方式存储 → 可以精确表示 0.10.20.3

2.2 特点

  • 高精度(28-29 位有效数字)
  • 范围比 double 小,但能避免浮点误差
  • 计算速度比浮点数慢(大约 5~20 倍),因为是软件实现而不是硬件指令

2.3 示例

decimal a = 0.1m + 0.2m;
decimal b = 0.3m;
Console.WriteLine(a == b); // True

👉 在货币、金融计算中,应优先使用 decimal

3️⃣ 性能对比

特性float/double(浮点数)decimal(定点数)
存储方式二进制科学计数法十进制定点数
精度有误差(约 15~16 位)高精度(28~29 位)
范围极大较小
运算速度硬件支持,速度极快慢(软件实现)
适用场景科学计算、物理模拟金融、货币

4️⃣ 小结

  • 浮点数 → 范围大、速度快,但存在精度误差
  • decimal → 精度高,适合金融,但性能较差
  • 判断浮点数相等时,应使用 近似比较 而不是 ==
  • 在游戏或物理模拟 → 用 float/double
  • 在账务、价格计算 → 用 decimal

到此这篇关于C# 浮点数与定点数详细解析的文章就介绍到这了,更多相关C# 浮点数与定点数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c# 用Base64实现文件上传

    c# 用Base64实现文件上传

    这篇文章主要介绍了c# 用Base64实现文件上传的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • WPF使用Dragablz构建可拖拽分离的Tab页程序

    WPF使用Dragablz构建可拖拽分离的Tab页程序

    这篇文章介绍了WPF使用Dragablz构建可拖拽分离Tab页的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • C#语法相比其它语言比较独特的地方(一)

    C#语法相比其它语言比较独特的地方(一)

    这篇文章主要介绍了C#语法相比其它语言比较独特的地方(一),本文讲解了switch语句可以用来测试string型的对象、多维数组、foreach语句、索引器和Property等内容,需要的朋友可以参考下
    2015-04-04
  • C#实现word文件下载的代码

    C#实现word文件下载的代码

    这篇文章主要介绍了C#实现word文件下载的代码,有需要的朋友可以参考一下
    2013-12-12
  • c#判断数据库服务器是否已经启动的方法

    c#判断数据库服务器是否已经启动的方法

    这篇文章主要介绍了使用c#判断数据库服务器是否已经启动的方法,大家参考使用吧
    2014-01-01
  • C# task应用实例详解

    C# task应用实例详解

    这篇文章主要介绍了如何在C#中一些应用task的实例,简单易懂的代码能更好的帮你学习,有兴趣的朋友可以了解下
    2020-05-05
  • C# xml序列化实现及遇到的坑

    C# xml序列化实现及遇到的坑

    在C#中,当我们需要将对象存储到文件或通过网络发送时,我们可以使用XML序列化将C#对象转换为XML文档,以便于存储、传输和还原,本文主要介绍了C# xml序列化实现及遇到的坑,感兴趣的可以了解一下
    2023-09-09
  • Unity Shader实现翻书效果

    Unity Shader实现翻书效果

    这篇文章主要为大家详细介绍了Unity Shader实现翻书效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • C#创建安全的栈(Stack)存储结构

    C#创建安全的栈(Stack)存储结构

    这篇文章主要为大家详细介绍了C#创建安全的栈(Stack)存储结构的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • 基于WPF实现瀑布流控件

    基于WPF实现瀑布流控件

    这篇文章主要介绍了如何基于WPF实现简单的瀑布流控件,文中的示例代码讲解详细,对我们的学习或工作有一定帮助,需要的小伙伴可以参考一下
    2024-02-02

最新评论