整數和浮點數在內存中的存儲(大小端字節序,浮點數的存取)

?

目錄

1.整數在內存中的存儲

2.大小端字節序和字節序判斷

2.1什么是大小端?

2.2為什么會有大小端

3.浮點數在內存中的存儲

3.1浮點數的存儲

3.1.1 浮點數存的過程

3.1.2 浮點數取的過程

3.2 解析

3.3 驗證浮點數的存儲方式


1.整數在內存中的存儲

整數的二進制表示方法有三種,即原碼、反碼、補碼。

三種表示方法均有符號位數值位兩部分,數值位的最高位被當作符號位,其中0表示“正”,1表示“負”,剩余的位則為數值位。

對于正整數,它的原碼、反碼、補碼都相同。

對與負整數,則三種表示方法各不相同:

原碼:直接將數值按照正負數的形式翻譯成?進制得到的就是原碼

反碼:將原碼的符號位不變,其他位依次按位取反就可以得到反碼

補碼:反碼+1就得到補碼

計算機再存儲整數時,存放的都是補碼。

原因是:

1.在計算機系統中,數值?律?補碼來表示和存儲。原因在于,使用補碼,可以將符號位和數值域統一處理;

2.同時,加法和減法也可以統?處理(CPU只有加法器)此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬件電路。

2.大小端字節序和字節序判斷

下面我們以一段代碼來觀察數據的存儲

通過調試,我們可以發現0x11223344這個數字是以字節為單位,倒著存儲的。

究其原因,我們了解到數據在內存中存儲的順序與大小端有關。

2.1什么是大小端?

大端(存儲)模式:是指數據的低位字節內容保存在內存的高地址處,而數據的高位字節內容,保存 在內存的低地址處。

小端(存儲)模式:是指數據的低位字節內容保存在內存的低地址處,而數據的高位字節內容,保存在內存的高地址處。

上面展示的就是按照小端模式存儲字節順序的。

我們也可以通過一端代碼來判斷我們的硬件是通過哪種模式來存儲字節順序的。

方法一:

#include<stdio.h>
int check()
{int i = 1;return (*(char*)&i);
}
int main()
{int b = check();if (b == 1)printf("小端");elseprintf("大端");return 0;
}

方法二:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{union {char a;int b;}u;u.b = 1;if (u.a == 1)printf("小端");elseprintf("大端");return 0;
}

2.2為什么會有大小端

在計算機系統中,是以字節為單位的,每個地址單元都 對應著?個字節,?個字節為8bit 位,但是在C語言中除了8 bit 的 char 之外,還有16 bit 的 short 型,32 bit 的 long 型(要看具體的編譯器),另外,對于位數大于8位的處理器,例如16位 或者32位的處理器,由于寄存器寬度大于一個字節,那么必然存在著一個如何將多個字節安排的問題。因此就導致了大端存儲模式和小端存儲模式。

例如:?個16bit 的 short 型 x ,在內存中的地址為 0x0010 , x 的值為 0x1122 ,那么 0x11 為高字節, 0x22 為低字節。對于?端模式,就將 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,剛好相反。我們常用的 X86 結構是小端模式,而KEIL C51 則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是大端模式還是小端模式。

3.浮點數在內存中的存儲

先看下面一段代碼的輸出結果是什么?

#include<stdio.h>
int main()
{int n = 9;float* pFloat = (float*)&n;printf("n的值為:%d\n", n);printf("*pFloat的值為:%f\n", *pFloat);*pFloat = 9.0;printf("num的值為:%d\n", n);printf("*pFloat的值為:%f\n", *pFloat);return 0;
}

在看到答案之前各位可以思考一下到底會輸出什么?

想必看到答案后,各位都應該和我最初看到答案是一樣懵。

對于上面的問題,其實就是關于浮點數在內存中的存儲方式。下面就來講講浮點數在內存中究竟是如何存儲的。

3.1浮點數的存儲

根據國際標準IEEE(電?和電??程協會) 754,任意?個?進制浮點數V可以表示成下面的形式:

? (?1)S 表示符號位,當S=0,V為正數;當S=1,V為負數

? M 表示有效數字,M是大于等于1,小于2的?

? 2 E 表示指數位

?舉例來說:

十進制的5.0,寫成二進制是 101.0 ,相當于 1.01×2^2 。 那么,按照上面V的格式,可以得出S=0,M=1.01,E=2。

十進制的-5.0,寫成二進制是 -101.0 ,相當于 -1.01×2^2 。那么,S=1,M=1.01,E=2。

IEEE 754規定:

對于32位的浮點數,最高的1位存儲符號位S,接著的8位存儲指數E,剩下的23位存儲有效數字M

對于64位的浮點數,最高的1位存儲符號位S,接著的11位存儲指數E,剩下的52位存儲有效數字M

3.1.1 浮點數存的過程

IEEE 754對有效數字M和指數E,還有?些特別規定。

前面說過, 1≤M<2 ,也就是說,M可以寫成 1.xxxxxx 的形式,其中xxxxxx表示小數部分。 IEEE 754規定,在計算機內部保存M時,默認這個數的第?位總是1,因此可以被舍去,只保存后?的 xxxxxx部分。比如保存1.01的時候,只保存01,等到讀取的時候,再把第?位的1加上去。這樣做的目的,是節省1位有效數字。以32位浮點數為例,留給M只有23位,將第?位的1舍去以后,等于可以保存24位有效數字。

對于指數E,它是一個無符號整數。

如果E為8為,則它的取值范圍是0~255;如果E為16位,則它的取值范圍位0~2047。但是,在科學計數法中是可以出現負數的,所以IEEE 754規定,,存?內存時E的真實值必須再加上 ?個中間數,對于8位的E,這個中間數是127對于11位的E,這個中間數是1023。比如,2^10的E是 10,所以保存成32位浮點數時,必須保存成10+127=137,即10001001。

3.1.2 浮點數取的過程

指數E從內存中取出可以分為三種情況:

E不全為0或不全為1

指數E的計算值減去127(或1023),得到真實值,再將有效數字前加上1。

例如,0.5的二進制形式0.1,由于規定整數部分必須為1,所以小數點向右移動一位,則為1.0*2^(-1),其 階碼為-1+127(中間值)=126,表?為01111110,?尾數1.0去掉整數部分為0,補?0到23位,其二進制表示為

0 01111110 00000000000000000000000

E全為0

這時,浮點數的指數E等于1-127(或者1-1023)即為真實值,有效數字M不再加上第?位的1,而是還 原為0.xxxxxx的小數。這樣做是為了表示±0,以及接近于0的很小的數字。

E全為1

這時,如果有效數字M全為0,表示±無窮大(正負取決于符號位s);

3.2 解析

回到之前提到的題目,為什么 9 還原成浮點數,就成了 0.000000 ?

首先看9是如何存儲在內存中的

0000 0000 0000 0000 0000 0000 0000 1001

然后,將 9 的?進制序列按照浮點數的形式拆分,得到第一位符號位s=0,后面8位的指數 E=00000000 , 最后23位的有效數字M=000 0000 0000 0000 0000 1001。

由于指數E全為0,所以符合E為全0的情況。因此,浮點數V就寫成:

V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146)

顯然,V是?個很?的接近于0的正數,所以??進制?數表?就是0.000000。

至于浮點數9.0,為什么整數打印是 1091567616?

首先,浮點數9.0等于二進制1001.0,換算成科學計數法是:1.001×2^3。

所以: 9.0? = ?(?1) ? ? 0 ?(1.001)? ? ?23 ,

最后寫成二進制形式就是

0 10000010 001 0000 0000 0000 0000 0000

這個32位的?進制數,被當做整數來解析的時候,就是整數在內存中的補碼,原碼正是 1091567616 。

3.3 驗證浮點數的存儲方式

以5.5為例,它的二進制表示為101.1,即1.011*2^2,則S=0,M=1.011,E=2+127=129,

最后寫成二進制形式就是

0 10000001 01100000000000000000000

?

____________________

?感謝你的閱讀,希望本文能夠對你有所幫助。如果你喜歡我的內容,記得點贊關注收藏我的博客,我會繼續分享更多的內容。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/714584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714584.shtml
英文地址,請注明出處:http://en.pswp.cn/news/714584.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PAT (Basic Level) Practice | 朋友數

如果兩個整數各位數字的和是一樣的&#xff0c;則被稱為是“朋友數”&#xff0c;而那個公共的和就是它們的“朋友證號”。例如 123 和 51 就是朋友數&#xff0c;因為 123 51 6&#xff0c;而 6 就是它們的朋友證號。給定一些整數&#xff0c;要求你統計一下它們中有多少個不…

億道信息輕工業三防EM-T195,零售、制造、倉儲一網打盡

厚度僅10.5mm&#xff0c;重量僅0.65千克的EM-T195&#xff0c;其緊湊而纖薄的設計為以往加固型平板帶來了全新的輕薄概念。盡管設計時尚、輕薄&#xff0c;但經過軍用認證的強固性仍然能夠承受所有具有挑戰性的環境條件。隨身攜帶無負擔的輕便性加上抗震功能使其成為餐廳、酒店…

C++_數據類型_字符型

作用 字符型變量用于顯示單個字符 語法 char ch a;注意 在顯示字符型變量時&#xff0c;用單引號將字符括起來&#xff0c;不要用雙引號單引號只能有一個字符&#xff0c;不可以是字符串 C和C中字符型變量只占用一個字節字符型變量并不是把字符本身放到內存中存儲&#xf…

Excel導出

目錄 Maven依賴 實體類 表頭列寬自適應處理器 行列凍結處理器 合并單元格處理器 工具類 Maven依賴 <!--easy excel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</vers…

數獨游戲(dfs)

代碼注釋如下 #include <iostream> using namespace std; const int N 10; bool col[N][N], rol[N][N], cell[3][3][N]; char g[N][N]; bool dfs(int x, int y) { //用bool這樣在找到一個方案就可以迅速退出if(y 9) x, y 0; //若y超出邊界&#xff0c;則第二…

S1---FPGA硬件板級原理圖實戰導學

視頻鏈接 FPGA板級實戰導學01_嗶哩嗶哩_bilibili FPGA硬件板級原理圖實戰導學 【硬件電路設計的方法和技巧-嗶哩嗶哩】硬件電路設計的方法和技巧01_嗶哩嗶哩_bilibili&#xff08;40min&#xff09; 【高速板級硬件電路設計-嗶哩嗶哩】 高速板級硬件電路設計1_嗶哩嗶哩_bil…

【RT-Thread基礎教程】郵箱的使用

文章目錄 前言一、郵箱的特性二、郵箱操作函數2.1 創建郵箱創建動態郵箱創建靜態郵箱 2.2 刪除郵箱2.3 發郵件2.4 取郵件 三、示例代碼總結 前言 RT-Thread是一個開源的實時嵌入式操作系統&#xff0c;廣泛應用于各種嵌入式系統和物聯網設備。在RT-Thread中&#xff0c;郵箱是…

輸入一個整數,輸出其最長連續因子。

輸入一個整數&#xff0c;輸出其最長連續因子。 例如 輸入&#xff1a;60 輸出&#xff1a;2 3 4 5 6 注意&#xff1a;1不算因子 輸入輸出格式 輸入描述: 輸入一個整數N&#xff0c;N<10000。 輸出描述: 輸出其最長連續因子&#xff0c;如果有多個最長&#xff0c;輸出…

HTML5浮動

1.標準文檔流組成 塊級元素&#xff08;block&#xff09; 內聯元素&#xff08;inline&#xff09; 2.display屬性 作用&#xff1a;指定HTML標簽的顯示方式 常用屬性 值 說明 block 塊級元素的默認值&#xff0c;元素會被顯示為塊級元素&#xff0c;該元素前后會帶有換行…

Linux UnixODBC安裝配置

配置 UnixODBC 夢之上關注IP屬地: 香港 0.2322020.12.09 13:23:10字數 1,202閱讀 5,447 麒麟&達夢適配系列: 1.麒麟服務器上安裝 DM8 2.配置 UnixODBC 3.beego-ORM 適配達夢 資源緊張的時候&#xff0c;服務器是大家共用的&#xff0c;上面部署了一堆服務。所以選用doc…

Lua速成(7)

一、Lua 元表(Metatable) 在 Lua table 中我們可以訪問對應的 key 來得到 value 值&#xff0c;但是卻無法對兩個 table 進行操作(比如相加)。 因此 Lua 提供了元表(Metatable)&#xff0c;允許我們改變 table 的行為&#xff0c;每個行為關聯了對應的元方法。 例如&#xf…

ShardingJdbc實戰-分庫分表

文章目錄 基本配置分庫分表的分片策略一、inline 行表達時分片策略algorithm-expression行表達式完整案例和配置如下 二、根據實時間日期 - 按照標準規則分庫分表標準分片 - Standard完整案例和配置如下 基本配置 邏輯表 邏輯表是指&#xff1a;水平拆分的數據庫或者數據表的相…

SpringBoot實戰(1)

SpringBoot總結 一,Spring 設計思想 OOP: 面向對象編程-》封裝、繼承、多態 BOP: 面向Bean編程-》一切從Bean開始 AOP: 面向切面編程-》解藕、專 人做專事 IOC: 控制反轉,將new 對象的操作交給Spring統一管理-》轉交控制權 DI/DL: 依賴注入/依賴查找-》自動賦值 DI和AOP…

LLVM 一些重要文檔 LLVM 3.0

基于LLVM 3.0: Documentation for the LLVM System at SVN head LLVM 作為庫的使用方法&#xff1a; Using The LLVM Libraries LLVM C 的編程規范&#xff1a; LLVM Coding Standards

stl 迭代器(Iterator)

定義 迭代器&#xff08;Iterator&#xff09;是STL&#xff08;Standard Template Library&#xff0c;標準模板庫&#xff09;中的一個核心概念&#xff0c;用于提供一種通用的方式來遍歷容器&#xff08;如vector、list、map等&#xff09;中的元素&#xff0c;而無需暴露容…

大小端問題

0. 介紹 大小端計算機存儲數據而安排字節的兩種順序。 針對的是字節。 大端與我們平時書寫的順序一致。 1. 大小端的判定 不需要手動判斷。 有一個頭文件endian.h; 可能會有宏 __BYTE_ORDER __BIG_ENDIAN __LITTLE_ENDIAN通過庫來進行判斷。 手動判斷 根據字節存取的順序…

【JSON2WEB】07 Amis可視化設計器CRUD增刪改查

總算到重點中的核心內容&#xff0c;CRUD也就是增刪改查&#xff0c;一個設計科學合理的管理信息系統&#xff0c;95%的就是CRUD&#xff0c;達不到這個比例要重新考慮一下你的數據庫設計了。 1 新增頁面 Step 1 啟動amis-editor Setp 2 新增頁面 名稱和路徑隨便命名&#xf…

Dynamo幕墻探究系列(一)

一直想寫個系列教程&#xff0c;但是沒有那么多時間整理資料&#xff0c;這次呢&#xff0c;先弄個小系列吧&#xff0c;還是和之前差不多的幕墻測試&#xff0c;我們分幾節課&#xff0c;一步一步深入研究。 今天先開個小頭兒&#xff0c;要弄的&#xff0c;就是下面這么個模型…

對象鎖與類鎖

不同鎖互不影響&#xff0c;共用一個鎖&#xff0c;可能會發生阻塞。 1.在修飾靜態方法時&#xff0c;鎖定的是當前類的 Class 對象&#xff0c;在下面的例子中就是SycTest1.class 2.當修飾非靜態方法時&#xff0c;鎖定的就是 this 對象&#xff0c;即當前的實例化對象 public…

【Git教程】(四)版本庫 —— 存儲系統,存儲目錄,提交對象及其命名、移動與復制~

Git教程 版本庫 1?? 一種簡單而高效的存儲系統2?? 存儲目錄&#xff1a;Blob 與 Tree3?? 相同數據只存儲一次4?? 壓縮相似內容5?? 不同文件的散列值相同6?? 提交對象7?? 提交歷史中的對象重用8?? 重命名、移動與復制&#x1f33e; 總結 事實上&#xff0c;我們…