網站首頁 編程語言 正文
一.回顧浮點數的存儲與讀取
浮點數的存入與讀取流程總覽:
二.浮點數使用的第一個注意事項
由于浮點數存入時很可能發生有效數值M二進制序列的截斷以及被截去的序列的最高位的四舍五入而造成精度損失,所以兩個浮點數直接用操作符進行比較很可能會得到不符合預期的結果。
舉個例子:
int main()
{
float a = 3.12f;
a += 0.02f;
float b = 3.14f;
std::cout << (a == b) << std::endl;
std::cout << (a > b) << std::endl;
std::cout << (a < b) << std::endl;
return 0;
}
簡單調試一下代碼:
上述代碼中,a最終的值和b的值在數學上應該是相同的,但是由于精度丟失而導致了最后a<b,如果這時a和b直接用運算符進行比較則無法得到預期的結果。
兩個浮點數的比較應該使用如下方式:
對于浮點數而言比較合適的精度為:0.000001
對于雙進度浮點數而言比較合適的精度為:0.0000000000000001
因此可以定義兩個宏:
#define epf 1e-6
#define epd 1e-16
f,f1,f2代表單精度浮點數,d,d1,d2代表雙精度浮點數。
判斷浮點數是否等于0:
要判斷一個單精度浮點數是否等于0:if(fabs(f) <= eps );
要判斷一個雙精度浮點數是否等于0:if(fabs(d) <= epd);
判斷兩個浮點數是否相等:
要判斷兩個單精度浮點數是否相等:if(fabs(f1 - f2) <= eps);
要判斷兩個雙精度浮點數是否相等:if(fabs(d1 - d2) <= epd);
注:fabs是求浮點數絕對值的函數。聲明在<iostream>頭文件中。
#define eps 1e-6
int main()
{
float a = 3.12f;
a +=0.02f;
float b = 3.14f;
if (fabs(a - b) <= eps)
{
std::cout << "a==b" << std::endl;
}
else
{
std::cout << "a!=b" << std::endl;
}
return 0;
}
三.浮點數使用的第二個注意事項?
由于浮點數存入時可能發生數據截斷,因此兩個絕對值相差巨大的浮點數進行加減運算很多時候是沒有意義的。
以十進制數為例來說明這個問題:
代碼驗證:
int main()
{
float a = 1e38;
std::cout << a << std::endl;
float b = 1000;
a = a + b;
std::cout << a << std::endl;
a = a - b;
std::cout << a << std::endl;
return 0;
}
附: 觀察內存中的FLT_MAX和FLT_MIN
C/C++中的FLT_MAX都被宏定義為浮點數絕對值最大的值
將FLT_MAX存入內存中:
將a的二進制序列分割為SEM的形式 :
其指數位不是全1
C/C++中的FLT_MIN被宏定義為絕對值最接近于0的浮點數?
將FLT_MIN存入內存中:
其指數位不是全0?
補充:C 語言兩個浮點數比較大小的辦法
浮點數并非真正意義上的實數,只是其在某個范圍內的近似。
因此兩個浮點數比較大小時,不能簡單地使用大于小于號進行比較,應該判斷連個浮點數差值的絕對值是否近似為0。
#include <stdio.h>
#include <math.h>
// 這里的 EPS 是自己定義的精度
#define EPS 1e-7 // 判斷浮點數是否位于0的一個很小的鄰域內[-EPS,EPS]內
int main(void)
{
/* 判斷一個浮點數是否等于 0*/
float a;
scanf("%f", &a);
if(fabs(a) <= EPS) // a=0
...
else if(a > EPS) // a>0
...
else // a<0
...
/* 比較兩個浮點數大小 */
float a,b;
scanf("%f%f",&a, &b);
if(fabs(a-b) <= EPS) // a=b
...
else if( (a-b) > EPS) // a>b
...
else // a<b
...
}
總結
原文鏈接:https://blog.csdn.net/weixin_73470348/article/details/128707623
相關推薦
- 2022-08-20 使用Docker制作Python環境連接Oracle鏡像_python
- 2022-12-11 C語言冷知識之預處理字符串操作符詳解_C 語言
- 2022-07-04 如何生成對角矩陣?numpy.diag_python
- 2022-04-05 Python?Opencv基于透視變換的圖像矯正_python
- 2023-05-31 E:?無法定位軟件包?python3-pip問題及解決_python
- 2022-06-02 C語言實現簡單的抽獎系統_C 語言
- 2022-09-08 go語言中函數與方法介紹_Golang
- 2024-02-28 CSS,文本溢出顯示省略號
- 最近更新
-
- 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同步修改后的遠程分支