網站首頁 編程語言 正文
一 先來看一段代碼
#include<stdio.h> int main() { double test=0.1; printf("%.100lf",test); return 0; }
運行結果:
?直接從現象說結果:精度丟失由于計算機二進制轉化過程中因為比特位過多發生數據的截斷導致的,這個結果是可以偏大也可以偏小的。
解釋一下:首先要知道二進制轉換為十進制的基本方法(除二取余法,乘五取余法等等),最好再了解一下浮點數的存儲,這里的0.1就是一個典型的例子,對0.1乘五取余是乘不盡的,那么數據轉化成的二進制序列的長度就會超出double的范圍。那么多出的數據就會被截斷。
二 如何解決
如果你想的是徹底讓屏幕顯示出來的是0.1,那么,你不孤單,我一開始也是這樣想的,但是這是不可能的。但是這個對我們的實際意義不大,畢竟有效的區段還是夠的。
我在這里具體要解決的是兩個問題
(1)浮點數的大小比較
#include<stdio.h> int main() { double test=0.1; if(test==(1-0.9)) { printf("正常"); } else { printf("what!!!"); } return 0; }
這段代碼會輸出“what!”。為什么上面已經說了0.1乘不盡,這里換成0.5是OK的,因為0.5D用二進制表示就是0.1B。每次都考慮乘不盡不煩嗎?
解決方案
引入庫函數<float.h>里定義的宏DBL_EPSILON。
?這里后面的一段英文是他是導致x+n!=x的最小值??(n代表EPSILON伊普西隆,x是任意值)
也就是說,任意一個比EPSILON小的值,你給一個數加上,都不會改變它的值。
那么,比EPSILON小的值引起的精度丟失都是在我們的允許范圍內的
#include<stdio.h> #include<float.h> #include<math.h> int main() { double test = 0.1; if (fabs(test - (1 - 0.9)) < DBL_EPSILON) { printf("正常"); } else { printf("what!!!"); } return 0; }
上圖有兩個點
1 。在<math.h>下的fabs(a)即取a的絕對值
想象一根數軸,他們相減的絕對值就是他們的距離
2 。 if(fabs(test-(1-0.9)<DBL_EPSILON))
等價于(test==1-0.9)(當然是對我們? ? ?人? ? ?而言)
test和(1-0.9)的距離若是小于DBL_EPSILON,那么精度的丟失是在可控范圍內的,說明他們倆相等
(2)含浮點數的表達式和0.0的比較
要先把上面的搞明白。
之所以單獨說這個問題,我是想強調一個數字與零作比較到底應該是a<DBL_EPSILON還是a<=DBL_EPSILON,加強一下理解
EPSILON是允許范圍內的最小值(回到宏定義后面的解釋),所以這個等于不可以加,加了說明上面的a如果等于EPSILION時,會導致數值的改變。
想要徹底解決精度丟失,是不可能的,也沒必要,但我們有辦法用近似來解決。
如果看完這篇文章你還是很迷糊,但我還是想說這是不能徹底解決的(我一開始也有這種想法),那么希望下次我準備出的數據的存取能對你有幫助。篇幅太長了,所以刪刪減減還是準備放到下次。
總結
原文鏈接:https://blog.csdn.net/m0_62853450/article/details/122439317
相關推薦
- 2022-08-02 Go語言kylin任務自動化實例詳解_Golang
- 2022-09-21 Mac安裝軟件時提示已損壞的完美解決方法_相關技巧
- 2022-09-09 python實現0到1之間的隨機數方式_python
- 2023-02-01 Python繪制正二十面體圖形示例_python
- 2022-06-29 一文教會你使用Nginx訪問日志統計PV與UV_nginx
- 2022-04-20 .NET?Core使用Worker?Service創建服務_實用技巧
- 2022-06-02 C/C++編程中const的使用詳解_C 語言
- 2022-05-28 python中數組和列表的簡單實例_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支