網站首頁 編程語言 正文
整形之間的強制轉換
在強制類型轉換中,我們常用的整形強制轉換有無符號和有符號類型的強制轉換。所以首先我們得介紹一下計算機中存儲數字的方式,計算機中通常以補碼的形式來存儲數據,以8位數據為例,二進制與有符號數的對應關系為:
0 | 1 | 2 | … | 127 | -128 | -127 | … | -1 |
---|---|---|---|---|---|---|---|---|
0000 0000 | 0000 0001 | 0000 0010 | … | 0111 1111 | 1000 0000 | 1000 0001 | … | 1111 1111 |
無符號轉有符號
0 | 1 | 2 | … | 127 | 128 | 129 | … | 255 |
---|---|---|---|---|---|---|---|---|
0000 0000 | 0000 0001 | 0000 0010 | … | 0111 1111 | 1000 0000 | 1000 0001 | … | 1111 1111 |
所以對于有符號數,首先最高位是正負的標志位。要將無符號數強制轉化為有符號數時,其內存上的二進制是不會改變的,只是我們對它的解釋變了,即無符號數128強制轉化有符號數即-128。
當然這樣引申出來的一種好處就是對于有符號數的判斷,如
char a; ... if((a>=0)&&(a<80)) { .... }
可以使用強制轉化,省去一個判斷條件
char a; ... if( ((unsigned char)a) < 80) { .... }
有符號轉無符號
將有符號數變成無符號數時,情況也類似,如8位的有符號數120轉無符號也是120,但8位的-1轉無符號則為255。所以當我們在有符號數的計算中,想保留大于等于0的數,不能通過強制轉化來完成,必須得加判斷:
char a,b,d;
unsigned char c;
....
c=(unsigned char)(a+b); (×):當運算結果小于0時c會異常,變成超級大數
d=a+b;
c = (d<0)?0:d; (√)
不同長度數字轉化中的截斷
比如我有一個8位的有符號數-1,要轉換為一個16位的有符號數,那么結果仍舊是-1。首先我們要明確一點,那就是雖然8位的有符號數-1的二進制原本1111 1111,但載入32位的cpu中運算時,它將轉化為32位的有符號數進行運算,即int類型的-1。所以對于char類型的數據,即使運算結果超過了該類型,其實也不會發生異常:
char a=127,b=127,c=127,e;
int d;
....
e=a+b+c; (×):當運算結果超過存儲類型的表示范圍時,會因截斷產生錯誤
d=a+b+c; (√):32位的int類型足夠存儲結果。
所以我們如果把不同長度的數字進行類型轉換,只有兩個步驟:
1、將該數表示為32位
2、將32位數截斷為結果類型
不過,可以確定的一點就是,進行第一步時,數的值不會發生變化:
比如8位有符號數-1(1111 1111)將轉化為32位的-1(1111 1111 1111 1111 … 1111 111)。
而8位的無符號數255(1111 1111)轉為32位時,也仍舊是255:(0000 0000…0000 0000 1111 111)。
但進行第二步轉換時,值會由于截斷而發生變化,而這個截斷一般是高位截斷(舍棄高位,保留低位):
如int類型的255(0000 0000 … 0000 0000 1111 1111)轉化為8為的unsigned char類型時,前面的0將被截斷,只保留低8位,即255(1111 1111),當然,若是轉為8為的有符號char類型,則為-1(1111 1111)。截斷是二進制層面的位數截斷,與實際值無關。
整形與浮點數的強制類型轉換
我們都知道浮點數float類型一般遵循ieee754標準,有符號位,階碼和尾數:
與整形相同,符號位是1時代表負數,是0則為正數。而階碼代表小數點在哪兒,類似于科學計數法100會被表示為 1.0 × 10^2。詳細的這里不介紹了,我們重點放在強制轉化上:
對于一個int類型的數,只要在浮點數的表示范圍內,便可以正確的轉為浮點數格式。
但是對于一個浮點類型的數,在轉化為整形時,則會只保留整數位,如:
int a= (int)0.1; 即a=0
int a= (int)1.1; 即a=1
int a= (int)1.5; 即a=1
int a= (int)-1.5; 即a=-1
所以如果要四舍五入之類的的,則不能靠強制轉換,得用相關的函數。當然若是轉為其他整形,則結果將有32位的整形結果進行截斷得到。
當然,強制轉換和 floor 這個函數的功能其實很像,floor函數的功能是向下取整:
int a= floorf(0.1); 即a=0
int a= floorf(1.1); 即a=1
int a= floorf(1.5); 即a=1
對于大于0的浮點數,他倆其實可以替換,而當小于0時,他倆區別很大:
int a= floorf(-0.1); 即a=-1
int a= floorf(-1.1); 即a=-2
int a=(int)-0.1; 即a=0
int a=(int)-1.1; 即a=-1
強制轉化的結果,會產生正負0這種概念,如-0.9到0.9強制轉化結果都為0。使用強制轉化時會產生越界輸出
總結
原文鏈接:https://blog.csdn.net/qq_43133135/article/details/122883705
相關推薦
- 2022-11-01 Git操作規范之tag的使用技巧詳解_相關技巧
- 2022-06-11 sql?server排查死鎖優化性能_MsSql
- 2022-05-28 基于ASP.NET實現驗證碼生成詳解_實用技巧
- 2022-08-13 Redis 性能影響 - 異步機制和響應延遲
- 2021-12-01 linux下umask命令用途原理和計算方式詳解_Linux
- 2022-07-31 C++?容器?Vector?的使用方法_C 語言
- 2022-05-06 Python判斷字符串中是否是中英文文小技巧
- 2022-11-05 GO?CountMinSketch計數器(布隆過濾器思想的近似計數器)_Golang
- 最近更新
-
- 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同步修改后的遠程分支