日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

深入理解计算机系统-之-数值存储(六)--以不同的方式窥视内存

發(fā)布時間:2025/7/14 windows 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解计算机系统-之-数值存储(六)--以不同的方式窥视内存 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

浮點數(shù)寫,整數(shù)讀


好了知道了浮點數(shù)的存儲方式,那么我們的問題來了,如果我們定義了一個浮點數(shù),那么如果以整數(shù)的格式去讀取它,會發(fā)生什么奇妙的現(xiàn)象

代碼示例


我們對上一篇文章中修改main函數(shù)為如下形式
我們定義了變量float f = 9.0f, 然后用一個整形指針去讀它,由于32位機器上int和float類型的大小是一致的,不會存儲訪問越界(即使是64位機器,int也不一定為不是32位,因為這個不僅跟機器字長相關(guān),還跟編譯器的處理方式相關(guān))

#include <stdio.h> #include <stdlib.h>int print_bit(void *addr, int size) {unsigned char *ptr = (unsigned char *)addr;int print_bytes = 0;if(ptr == NULL){return -1; }for(print_bytes = 0;print_bytes < size;print_bytes++, ptr++){ #ifdef DEBUGprintf("byte %d, data = %02x -=>", print_bytes, *ptr); #endiffor(int print_bits = 7;print_bits >= 0;print_bits--){printf("%d", ((*ptr >> print_bits) & 1));} #ifdef DEBUGprintf("\n"); #endif}printf("\n"); return print_bytes; }int print_byte(void *addr, int size) {unsigned char *paddr = (unsigned char *)addr;int print_bytes = 0;if(paddr == NULL){return -1; }while(print_bytes < size){printf("%02x", *paddr); paddr++; print_bytes++; }printf("\n"); return print_bytes; }int main(void) {printf("%d == %d\n", sizeof(float), sizeof(int));float f = 9.0f; //對于一塊內(nèi)存,按浮點型初始化int * pInt = (int *)(&f);print_byte((void *)&f, sizeof(f));print_bit((void *)&f, sizeof(f));printf("the float : %f, %f\n", f, *pInt); //以浮點視角看printf("the int : %d, %d, %d\n", f, (int)f, *pInt); //以整型視角看*pInt = 9;print_byte((void *)&f, sizeof(f));print_bit((void *)&f, sizeof(f));printf("the float : %f, %f\n", f, *pInt); //以浮點視角看printf("the int : %d, %d, %d\n", f, (int)f, *pInt); //以整型視角看return EXIT_SUCCESS; }

float 9.0表示出來 =1001×2?0?=1.001×2?3??
階碼=3 +127 =130 =10000010B

符號位階碼尾數(shù)
01000001000100000000000000000000

存儲起來就是0x41100000H

浮點數(shù)讀


第一種讀取方式:直接對這個浮點數(shù)按照整數(shù)方法讀取


這個不需要多說什么,存儲格式與讀取格式一致

第二種讀取方式:用pInt型指針按照浮點數(shù)格式讀取


首先,將0x00000009拆分,得到第一位符號位s=0,后面8位的指數(shù)E=00000000,最后23位的有效數(shù)字M=000 0000 0000 0000 0000 1001。
由于指數(shù)E全為0,所以符合上一節(jié)的第二種情況。因此,浮點數(shù)V就寫成:
V=(-1)^0×0.00000000000000000001001×2^(-126)=1.001×2^(-146)
顯然,V是一個很小的接近于0的正數(shù),所以用十進制小數(shù)表示就是0.000000。

整數(shù)讀


第一種方式,直接printf以”%d”輸出浮點數(shù)f


這種方式下,出現(xiàn)了一個奇妙的問題,我們的浮點數(shù)9.0f用%d輸出后,變成了0.0。
這是為什么呢。因為在C語言中浮點數(shù)默認為雙精度(double),除非指定F,但是printf打印時對于單精度浮點數(shù),仍然要轉(zhuǎn)換成雙精度浮點數(shù)然后打印,因此

printf("%d", f) <-==->printf("%d", 9.0f);
  • 1
  • 1

會進行如下處理

單精度浮點數(shù):9.0F = 0 | 10000010| 00100000000000000000000

  • 求出它的單精度內(nèi)存表示,
  • 轉(zhuǎn)換為雙精度,有效位不足補0,
  • 輸出低32位所表示的十進制數(shù)
    總的來說,在打印一個浮點數(shù)時,一.浮點數(shù)轉(zhuǎn)換成雙精度 二. 打印低32位.

因此打印的結(jié)果始終為0

第二種方式,強制轉(zhuǎn)換后去讀取


將浮點數(shù)(單雙精度)轉(zhuǎn)換為整數(shù)時,將舍棄浮點數(shù)的小數(shù)部分, 只保留整數(shù)部分。將整型值賦給浮點型變量,數(shù)值不變,只將形式改為浮點形式, 即小數(shù)點后帶若干個0。

注意:賦值時的類型轉(zhuǎn)換實際上是強制的。

因此顯示的結(jié)果是9

第三種讀取方式:用一個int型的指針去讀取


這個也比較好理解,由于我們用了一個int行的指針去讀取
那么編譯器處理時會認為這個是一個int型的變量
回到前面float 9.0表示出來是

符號位階碼尾數(shù)
0100001100110010001000000000

小端模式的存儲結(jié)構(gòu)為00001041,編譯器出來以后會·按字節(jié)進行整合,

存儲的int值其實是0x41100000H = 1091567616

第二次讀寫


接著我們用整形指針向f中寫入了數(shù)據(jù) *pInt = 9; 雖然我們看起來好像沒什么變化,但是其實寫入的數(shù)據(jù)已經(jīng)發(fā)生了很大變化,因為前面的兩篇博文我們已經(jīng)看到,整數(shù)和浮點數(shù)的存儲格式是有很大區(qū)別的。
這個操作其實是將一個單精度浮點數(shù)標識的9.0f的存儲格式,強制變成了整數(shù)9的存儲格式。
因此進行浮點數(shù)讀全為0(階碼為0)
而我們用pInt去按照整數(shù)讀取的時候,由于存儲格式本來就是整數(shù)的存儲格式,因此讀取出來是9

整數(shù)寫,浮點數(shù)讀

跟上一個例子相反,我們定一個int型變量,然后用float型的指針進行讀取

int main(void) {printf("%d == %d\n", sizeof(float), sizeof(int));int num = 9; /* num是整型變量,設(shè)為9 */float* pFloat = (float *)&num; /* pFloat表示num的內(nèi)存地址,但是設(shè)為浮點數(shù) */print_byte((void *)&num, sizeof(num));print_bit((void *)&num, sizeof(num));printf("the float : %f, %f\n", num, *pFloat); //以浮點視角看printf("the int : %d, %d\n", (int)num, *pFloat); //以整型視角看*pFloat = 9.0f; /* 將num的值改為浮點數(shù) */print_byte((void *)&num, sizeof(num));print_bit((void *)&num, sizeof(num));printf("the float : %f, %f\n", num, *pFloat); //以浮點視角看printf("the int : %d, %d\n", (int)num, *pFloat); //以整型視角看return EXIT_SUCCESS; }

同樣我們這個代碼,用上面的分析就很簡單了。也不過是將一個浮點數(shù)的存儲格式,強制變成了整數(shù)的存儲格式而已


轉(zhuǎn)載:http://blog.csdn.net/gatieme/article/details/50709093

總結(jié)

以上是生活随笔為你收集整理的深入理解计算机系统-之-数值存储(六)--以不同的方式窥视内存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。