C#?浮點數(shù)與定點數(shù)的原理與用法對比
C# 浮點數(shù)與定點數(shù)詳細解析
在 C# 中,數(shù)值類型主要分為:
- 整數(shù)型(
int,long等) - 浮點型(
float,double) - 定點型(
decimal)
浮點數(shù)和定點數(shù)在內(nèi)部的表示方式不同,導(dǎo)致它們的 精度、范圍、性能、使用場景 都有明顯區(qū)別。本文將詳細剖析兩者的原理與對比。
1?? 浮點數(shù)(float / double)
1.1 表示方法(IEEE 754)
浮點數(shù)采用 二進制科學計數(shù)法 存儲:
值 = (-1)^符號位 × 1.尾數(shù) × 2^(指數(shù) - 偏移量)
- 符號位:1 位,表示正負
- 指數(shù)位:控制縮放大小
- 尾數(shù)位:存儲有效數(shù)字
| 類型 | 位數(shù) | 符號位 | 指數(shù)位 | 尾數(shù)位 |
|---|---|---|---|---|
| float | 32 | 1 | 8 | 23 |
| double | 64 | 1 | 11 | 52 |
?? 范圍極大,但精度有限。某些小數(shù)在二進制中無法精確表示。
1.2 小數(shù)的二進制表示
浮點數(shù)小數(shù)用 2 的負次方來組合:
0.101? = 2?1 + 2?3 = 0.5 + 0.125 = 0.625
但像 0.1 這樣的十進制分數(shù),在二進制中是無限循環(huán)小數(shù):
0.1?? = 0.0001100110011...?
只能近似存儲 → 運算會出現(xiàn)誤差。
1.3 常見誤差示例
Console.WriteLine(0.1 + 0.2 == 0.3); // False Console.WriteLine(0.1 + 0.2); // 0.30000000000000004
原因:二進制截斷 → 加法結(jié)果不是精確的 0.3。
1.4 特殊值
浮點數(shù)里其實還藏著幾個特別的數(shù),它們在實際開發(fā)里經(jīng)常會遇到:
- 正無窮 / 負無窮
- 當結(jié)果太大,已經(jīng)超過浮點數(shù)能表示的范圍時,就會變成無窮大:
double.PositiveInfinity→ 正無窮double.NegativeInfinity→ 負無窮- NaN(Not a Number,意思是“不是一個數(shù)”)
- 一些數(shù)學上不合法的運算會得到 NaN,比如:
Console.WriteLine(double.NaN == double.NaN); // false
0.0 / 0.0Math.Sqrt(-1)- 特別注意:
NaN和任何值比較(甚至跟自己比)都會是false。 - +0 和 -0
- 浮點數(shù)里其實區(qū)分正零和負零,不過在大多數(shù)運算里,它們沒區(qū)別:
+0 == -0結(jié)果是true- 但在某些場景(比如除法)下會有區(qū)別:
Console.WriteLine(1.0 / +0); // Infinity Console.WriteLine(1.0 / -0); // -Infinity
1.5 浮點數(shù)比較正確姿勢
- 近似比較(epsilon 容差)
bool IsEqual(double a, double b, double eps = 1e-10)
=> Math.Abs(a - b) < eps;
- 游戲開發(fā)常見做法(Godot / Unity)
Mathf.Approximately(a, b); // Unity Mathf.IsEqualApprox(a, b); // Godot
- 避免直接用
==
除非數(shù)據(jù)本身是整數(shù)運算得來的,或者特別確定是完全相等。
2?? 定點數(shù)(decimal)
2.1 表示方法
- 總共 128 位存儲:
- 96 位存有效數(shù)字
- 16 位存小數(shù)位精度(scale,小數(shù)點位置)
- 十進制方式存儲 → 可以精確表示
0.1、0.2、0.3。
2.2 特點
- 高精度(28-29 位有效數(shù)字)
- 范圍比
double小,但能避免浮點誤差 - 計算速度比浮點數(shù)慢(大約 5~20 倍),因為是軟件實現(xiàn)而不是硬件指令
2.3 示例
decimal a = 0.1m + 0.2m; decimal b = 0.3m; Console.WriteLine(a == b); // True
?? 在貨幣、金融計算中,應(yīng)優(yōu)先使用 decimal。
3?? 性能對比
| 特性 | float/double(浮點數(shù)) | decimal(定點數(shù)) |
|---|---|---|
| 存儲方式 | 二進制科學計數(shù)法 | 十進制定點數(shù) |
| 精度 | 有誤差(約 15~16 位) | 高精度(28~29 位) |
| 范圍 | 極大 | 較小 |
| 運算速度 | 硬件支持,速度極快 | 慢(軟件實現(xiàn)) |
| 適用場景 | 科學計算、物理模擬 | 金融、貨幣 |
4?? 小結(jié)
- 浮點數(shù) → 范圍大、速度快,但存在精度誤差
- decimal → 精度高,適合金融,但性能較差
- 判斷浮點數(shù)相等時,應(yīng)使用 近似比較 而不是
== - 在游戲或物理模擬 → 用
float/double - 在賬務(wù)、價格計算 → 用
decimal
到此這篇關(guān)于C# 浮點數(shù)與定點數(shù)詳細解析的文章就介紹到這了,更多相關(guān)C# 浮點數(shù)與定點數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#服務(wù)器NFS共享文件夾搭建與上傳圖片文件的實現(xiàn)
本文主要介紹了C#服務(wù)器NFS共享文件夾搭建與上傳圖片文件的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07
使用C#發(fā)送Http請求實現(xiàn)模擬登陸實例
本文主要介紹了使用C#發(fā)送Http請求實現(xiàn)模擬登陸實例,模擬登陸的原理簡單,想要了解的朋友可以了解一下。2016-10-10
在C#使用字典存儲事件示例及實現(xiàn)自定義事件訪問器
這篇文章主要介紹了在C#使用字典存儲事件示例及實現(xiàn)自定義事件訪問器的方法,是C#事件編程中的基礎(chǔ)知識,需要的朋友可以參考下2016-02-02
使用C#實現(xiàn)Excel實時讀取并導(dǎo)入SQL數(shù)據(jù)庫
這篇文章主要介紹了如何使用C#實現(xiàn)一個實時文件監(jiān)控模塊、Excel數(shù)據(jù)讀取模塊、數(shù)據(jù)庫批量插入模塊以及異常處理與日志模塊,從而實現(xiàn)Excel文件到SQL數(shù)據(jù)庫的高效導(dǎo)入,文章還討論了性能測試和部署建議,需要的朋友可以參考下2026-01-01

