數據的存儲---整型、浮點型

目錄

一、整型在內存中的存儲

1. 原碼、反碼、補碼

2. 大端與小端

二、浮點數在內存中的存儲

1.浮點數的存

2. 浮點數的取

3. 題目解析


一個變量的創建需要在內存中開辟空間,而開辟的空間大小是由數據類型決定的。下面我們就來討論一下整型、浮點型在內存中的儲存。

一、整型在內存中的存儲

1. 原碼、反碼、補碼

整數的2進制表述方法有三種:原碼、反碼、補碼

對于有符號整數,這三種表示形式均有兩部分組成:(1)符號位,(2)數值位。

而對于無符號整數,則只有數值位。

在2進制序列中最高位是符號位,其余都是數值位。對于符號位而言,用 “ 0 ” 表示正,用 “ 1 ” 表示負。

正數的原、反、補碼都相同。

負整數的三種表示方法各不相同。

對于負數而言:

原碼

直接將數值按照正負數的形式翻譯成二進制就可以得到原碼。

反碼

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

補碼

反碼+1就得到補碼。

當然,反碼到原碼也可以先取反,再+1。

原碼、反碼、補碼三則之間的轉換方法:

對于整形來說:數據存放內存中其實存放的是補碼?

這是因為:

使用補碼,可以將符號位和數值域統 一處理。

同時,由于中央處理器(CPU)只有加法器,這樣加法和減法就可以統一處理了。

此外,補碼與原碼相互轉換,其運算過程 是相同的,不需要額外的硬件電路。

示例:

#include <stdio.h>
int main()
{int a = 20;int b = -10;int c = a + b;printf("%d\n", c);return 0;
}

這個代碼的計算過程:

但是如果你用原碼來計算:

這樣計算的結果為:20 - 10 = -30 ,明顯不成立。所以在內存中存放的是補碼,計算時是有補碼來計算的。

2. 大端與小端

知道了整型數字在內存中的存儲形式之后,那也要知道它在內存中的存儲位置。下面就來討論一下它在內存中的存儲位置關系。

對于存儲16進制的a變量的存儲方式的理解,就需要理解大端與小端的介紹。

首先需要了解一下,大端與小端的存儲概念。

大端字節存儲:是指低位字節的數據保存在內存的高地址中,而高位字節的數據保存在內存的低地址中。簡稱?大端

小端字節存儲:是指低位字節的數據保存在內存的低地址中,而高位字節的數據保存在內存的高地址中。簡稱?小端。

圖解:

下圖是編譯器中一個小端存儲的示例:

為什么會出現大小端的區分呢?

????????這是因為在計算機系統中,是以字節為單位的,?每個地址單元都對應著?個字節?,?個字節為8bit位,但是在C語言中除了8bit的 char 之外,還有16bit的 short 型,32bit的 int 型等,所以只有char型的數據能在一個地址單元中存儲,而大于8bit的類型就需要分配到多個地址單元中。

????????另外,對于位數大于8位的處理器,例如16位或者32位的處理器,由于寄存器寬度大于一個字節,那么必然存在著?個如何將多個字節安排的問題。因此就導致了大端存儲模式和小端存儲模式。

????????我們常用的 X86 結構是小端模式,而?KEIL C51 則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是 大端模式還是小端模式。

下面的一個練習可以很好的體現出大小端的應用。

  • 題目:用一個小程序來拍段當前機器的字節序(即判斷大端與小端)。

這個問題可以這樣解決:

先定義一個 int a = 1,由于1的16進制是00 00 00 01,然后再用char型的指針去取出這個int型的1的第一個字節數據。若這個指針指向的數據是1,則為小端,若為0,則為大端。

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

二、浮點數在內存中的存儲

首先來看以下代碼及其運行結果:

為什么會出現這種情況呢?

這其實是因為浮點型與整型的存儲方式是不同的。

1.浮點數的存

要理解上述這個結果,?定要搞懂浮點數在計算機內部的表示方法,即浮點數是怎么存的?

根據國際標準IEEE(電氣和電子工程協會)754,任意一個二進制浮點數 V 可以表成下面的形式:V ? = ?(?1)^S ? M ? 2^E

  • (?1) ^S表示符號位,當S=0,V為正數;當S=1,V為負數
  • M表示有效數字,M是大于等于1,小于2的
  • 2^E表示指數位

比如:根據上述規則,十進制的5.5,寫成二進制是101.1,則二進制的科學計數法為:1.011*2^2,相當于:(-1)^0*1.011*2^2,那么S=0,M=1.011,E=2 。

正因為任意一個二進制浮點數都可以用S,M,E這三個字母來表示,所以就有了以下規定:

IEEE754規定:

  • ?對于32位的浮點數(float),最高的1位存儲符號位S,接著的8位存儲指數E,剩下的23位存儲有效數字 M
  • 對于64位的浮點數(double),最高的1位存儲符號位S,接著的11位存儲指數E,剩下的52位存儲有效數字M

當然在這之中,對于存的“ M ”“?E ”也有一些特別的規定:

?1. 對于 M

看到上面的規定,可以發現二進制?M 的范圍是:1~2 ,所以M就可以寫成? 1.xxxxxxx??的形式,其中??xxxxxxx??是小數部分。也就是說,對于任意的M,其中要改變的只有它的小數部分。

所以IEEE 754又有規定:

在計算機內部保存M時,默認這個數的第一位總是1,因此可以被舍去,只保存后面的 xxxxxx部分,所以內存中保存的M只有小數部分。

比如在保存1.01的時候,只保存01,等到讀取的時候,才會把第一位的1加上去。

這樣做的目的是:節省1位有效數字。

對32位浮點數來說,留給M只有23位,將第一位的1舍去以后,就等于可以保存24位有效數字(23位的小數部分+1位隱含的1)。

對64位浮點數來說,留給M只有52位,將第一位的1舍去以后,就等于可以保存53位有效數字(52位的小數部分+1位隱含的1)。

?2. 對于 E

首先,要知道E為一個無符號整數(unsigned int)

這意味著,如果E為8位,它的取值范圍為0~255;如果E為11位,它的取值范圍為0~2047。

但是,我們在使用科學計數法時可以發現,科學計數法中的E是可以出現負數的,

所以IEEE 754規定:

存入內存時E的真實值必須再加上一個中間數,對于8位的E,這個中間數是127;對于11位的E,這個中間數是1023。

比如:2^10的E是 10,所以在保存成32位浮點數時,必須保存成10+127=137,即:10001001

知道了上述關于M和E的特點,就可以掌握 浮點數的存 的操作了。來看下面的一個示例:

2. 浮點數的取

知道了浮點數的存,那么就應該也要知道浮點數時怎么取出來的。

對于S和M來說,怎么存的就怎么取出去。但是對于E來說,就要分三種情況。

E不全為0或不全為1(常規情況)

這時需要采用以下規則:

指數E的計算值減去127(32位的浮點數)或1023(64位的浮點數),得到真實值,再將有效數字M前加上第?位的1。

比如:

32位的浮點數。存操作:0.5的二進制為:0.1,由于M的規定整數部分一定為1,則需要將小數點向右移動一位,即1.0*2^(-1) ,此時的 E = -1 + 127(中間值) = 126 ,表示為:01111110,而尾數1.0去掉整數部分為0,補齊23位,所以保存的M為:00000000000000000000000

0,5的在內存即為:? 0 01111110 00000000000000000000000

取的操作:第一位為0,則S=0;中間的8為01111110,即為126,這時需要減去127,得到-1,故E= -1,最后23為均為0,則M的小數部分就為0,再將有效數字M前加上第?位的1。,得到M=1.0,最后代入公式:V ? = ?(?1)^S ? M ? 2^E,?得到二進制:0.1,再轉化為十進制為:0.5。

E全為0

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

如:

在內存中的存儲:0 00000000 00100000000000000000000 ?

現在要將它取出來,通過這32位二進制,可以得到S=0,M=1.001,由于這里的E保存的是全0,所以,E的真實值被規定等于1-127,即為-126,這時若通過公式來算:V ? = ?(?1)^S ? M ? 2^E = (-1)^0*0.001*2^(-126),可以發現,此時V是一個及其小的數,無限接近于0了,所以在編譯器中會把它默認為是0。

E全為1

這時,表示的是正負無窮大(正負取決于符號位s);

0 11111111 00010000000000000000000

3. 題目解析

回顧剛剛的問題:

現在對這個應該有了很好的理解了吧。

首先,由于n是整型,所以n的二進制補碼就為:0000 0000 0000 0000 0000 0000 0000 1001

以%d打印就是打印這個補碼的原碼的十進制數。

當它強制性轉化為浮點數后,再用%f打印,就會對這個二進制進行拆分,可以得到S=0,E=1-127=-126,M=000 0000 0000 0000 0000 1001,E為全0,所以這個浮點數是一個無限接近0的數,所以打印的就是0.000000.

當它以浮點數的形式存進去,根據公式,則S=0,M=1.001,E=3+127=130,則得到的二進制為:0 10000010 001 0000 0000 0000 0000 0000

當它以%d的形式打印時,會認為它是補碼0100 0001 0001 0000 0000 0000 0000 0000

所以會打印出1,091,567,616

當以%f打印時,則會以0 10000010 001 0000 0000 0000 0000 0000,先得到S=0,M=1.001,E=130-127=3,然后再以公式計算得到并輸出9.000000

本篇文章到此結束!

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

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

相關文章

Java 大視界 -- Java 大數據在智能教育虛擬實驗室建設與實驗數據分析中的應用(132)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

??Jolt -- 通過JSON配置來處理復雜數據轉換的工具

簡介&#xff1a;一個能夠通過JSON配置&#xff08;特定的語法&#xff09;來處理復雜數據轉換的工具。 比如將API響應轉換為內部系統所需的格式&#xff0c;或者處理來自不同來源的數據結構差異。例如&#xff0c;將嵌套的JSON結構扁平化&#xff0c;或者重命名字段&#xff0…

47.全排列 II

47.全排列 II 力扣題目鏈接 給定一個可包含重復數字的序列 nums &#xff0c;按任意順序 返回所有不重復的全排列。 示例 1&#xff1a; 輸入&#xff1a;nums [1,1,2] 輸出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]]示例 2&#xff1a; 輸入&#xff1a;nums [1,2,3] 輸出…

centos沒有ll

vi /etc/bashrc alias ll‘ls -l’ source /etc/bashrc

04 1個路由器配置一個子網的dhcp服務

前言 這是最近一個朋友的 ensp 相關的問題, 這里來大致了解一下 ensp, 計算機網絡拓撲 相關基礎知識 這里一系列文章, 主要是參照了這位博主的 ensp 專欄 這里 我只是做了一個記錄, 自己實際操作了一遍, 增強了一些 自己的理解 當然 這里僅僅是一個 簡單的示例, 實際場景…

網絡空間安全(31)安全巡檢

一、定義與目的 定義&#xff1a; 安全巡檢是指由專業人員或特定部門負責&#xff0c;對各類設施、設備、環境等進行全面或重點檢查&#xff0c;及時發現潛在的安全隱患或問題。 目的&#xff1a; 預防事故發生&#xff1a;通過定期的安全巡檢&#xff0c;及時發現并解決潛在的…

在IGH ethercat主站中Domain和Entry之間的關系

在 IGH EtherCAT 主站中&#xff0c;“domain”&#xff08;域&#xff09;和 “entry”&#xff08;條目&#xff09;存在著緊密的關系&#xff0c;具體如下&#xff1a; 數據組織與管理方面&#xff1a;“domain” 是 EtherCAT 主站中用于管理和處理從站配置、數據映射和數據…

信息學奧賽一本通 1449:【例題2】魔板

題目 1449&#xff1a;【例題2】魔板 分析 首先注意&#xff1a;輸入是按順時針給出的&#xff0c;但我們處理時需要按正常順序排&#xff0c;可以用以下代碼讀入 string s(8, 0); // 初始化全零字符串 cin>>s[0]>>s[1]>>s[2]>>s[3]; cin>>…

Unity開發的抖音小游戲接入抖音開放平臺中的流量主(抖音小游戲接入廣告)

前言:作者在進行小游戲審核版本的過程中,碰到了下列問題,所以對這個抖音小游戲接入廣告研究了下。 還有就是作者的TTSDK版本號是6.2.6,使用的Unity版本是Unity2022.3.29f1,最好和作者的兩個版本號保持一致,因為我發現TTSDK舊版的很多函數在新版中就已經無法正常使用了,必…

【xv6操作系統】系統調用與traps機制解析及實驗設計

【xv6操作系統】系統調用與traps機制解析及實驗設計 系統調用相關理論系統調用追溯系統調用實驗設計Sysinfo&#x1f6a9;系統調用總結&#xff08;結合trap機制&#xff09; traptrap機制trap代碼流程Backtrace實驗alarm實驗 系統調用 相關理論 隔離性&#xff08;isolation)…

Docker文件夾上傳秘籍Windows下的高效傳輸之道

哈嘍,大家好,我是木頭左! 一、理解Docker容器與Windows文件系統的差異 在深入探討如何從 Windows 系統將文件夾及遞歸文件夾和文件上傳到 Docker 容器之前,有必要先明晰 Docker 容器與 Windows 文件系統之間存在的本質差異。 (一)Docker 容器的文件系統特性 Docker 容…

08 | 實現版本號打印功能

提示&#xff1a; 所有體系課見專欄&#xff1a;Go 項目開發極速入門實戰課&#xff1b;歡迎加入 云原生 AI 實戰 星球&#xff0c;12 高質量體系課、20 高質量實戰項目助你在 AI 時代建立技術競爭力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本節課最終…

在微信小程序或前端開發中,picker 和 select 都是用戶交互中用于選擇的組件,但它們在功能、設計和使用場景上有一定的區別

在微信小程序或前端開發中&#xff0c;picker 和 select 都是用戶交互中用于選擇的組件&#xff0c;但它們在功能、設計和使用場景上有一定的區別。 1. picker 的特點 描述&#xff1a; picker 是微信小程序中的原生組件&#xff0c;通常用于選擇單項或多項值&#xff0c;如時…

PMP 證書的含金量怎么樣?

pmp含金量&#xff0c;這是一個很有爭議的話題&#xff0c;我根據我以往的面試跟工作經歷對 PMP 也有幾點看法&#xff0c;想跟大家聊一聊。 一、如果真心想做項目管理&#xff0c;PMP 一定要去考一個 現在的早已不是憑經驗做項目的時代了&#xff0c;各大企業都追求專業式的…

Springboot連接neo4j

?一、Spring Data Neo4j 核心知識體系 ?1. 核心概念 ?圖數據庫特性&#xff1a; 數據以 ?節點&#xff08;Node&#xff09;? 和 ?關系&#xff08;Relationship&#xff09;? 形式存儲&#xff0c;支持屬性&#xff08;Property&#xff09;。查詢語言&#xff1a;Cyp…

我與DeepSeek讀《大型網站技術架構》- 大型網站架構技術一覽與Web開發技術發展歷程

文章目錄 大型網站架構技術一覽1. 前端架構2. 應用層架構3. 服務層架構4. 存儲層架構5. 后臺架構6. 數據采集與監控7. 安全架構8. 數據中心機房架構 Web開發技術發展歷程一、靜態HTML階段二、CGI腳本模式階段三、服務器頁面模式階段 大型網站架構技術一覽 1. 前端架構 瀏覽器…

Python數據類型進階——詳解

—— 小 峰 編 程 目錄 1.整型 1.1 定義 1.2 獨有功能 1.3 公共功能 1.4 轉換 1.5 其他 1.5.1 長整型 1.5.2 地板除(除法&#xff09; 2. 布爾類型 2.1 定義 2.2 獨有功能 2.3 公共功能 2.4 轉換 2.5 其他 做條件自動轉換 3.字符串類型 3.1 定義 3.2 獨有功能…

GNU Binutils 全工具指南:從編譯到逆向的完整生態

1. GNU Binutils 全工具指南&#xff1a;從編譯到逆向的完整生態 1. GNU Binutils 全工具指南&#xff1a;從編譯到逆向的完整生態 1.1. 引言1.2. 工具分類速查表1.3. 核心工具詳解 1.3.1. 編譯與匯編工具 1.3.1.1. as&#xff08;匯編器&#xff09;1.3.1.2. gcc&#xff08;…

docker python:latest鏡像 允許ssh遠程

跳轉到家目錄 cd創建pythonsshdockerfile mkdir pythonsshdockerfile跳轉pythonsshdockerfile cd pythonsshdockerfile創建Dockerfile文件 vim Dockerfile將Dockerfile的指令復制到文件中 # 使用 python:latest 作為基礎鏡像 # 如果我的鏡像列表中沒有python:latest鏡像&…

c++的基礎排序算法

一、快速排序 1. 選擇基準值&#xff08;Pivot&#xff09; 作用 &#xff1a;從數組中選擇一個元素作為基準&#xff08;Pivot&#xff09;&#xff0c;用于劃分數組。常見選擇方式 &#xff1a; 固定選擇最后一個元素&#xff08;如示例代碼&#xff09;。隨機選擇&#xf…