浮點數在計算機中存儲方式

C語言和C#語言中,對于浮點類型的數據采用單精度類型(float)和雙精度類型(double)來存儲,float數據占用32bit,double數據占用64bit,我們在聲明一個變量float f= 2.25f的時候,是如何分配內存的呢?如果胡亂分配,那世界豈不是亂套了么,其實不論是float還是double在存儲方式上都是遵從IEEE的規范的,float遵從的是IEEE R32.24 ,而double 遵從的是R64.53。

??? 無論是單精度還是雙精度在存儲中都分為三個部分:

  1. 符號位(Sign) : 0代表正,1代表為負
  2. 指數位(Exponent):用于存儲科學計數法中的指數數據,并且采用移位存儲
  3. 尾數部分(Mantissa):尾數部分

?其中float的存儲方式如下圖所示:

float類型的存儲方式

而雙精度的存儲方式為:

?

double類型數據的存儲方式

????R32.24和R64.53的存儲方式都是用科學計數法來存儲數據的,比如8.25用十進制的科學計數法表示就為:8.25*clip_image0021,而120.5可以表示為:1.205*clip_image0022,這些小學的知識就不用多說了吧。而我們傻蛋計算機根本不認識十進制的數據,他只認識0,1,所以在計算機存儲中,首先要將上面的數更改為二進制的科學計數法表示,8.25用二進制表示可表示為1000.01,我靠,不會連這都不會轉換吧?那我估計要沒轍了。120.5用二進制表示為:1110110.1用二進制的科學計數法表示1000.01可以表示為1.0001*clip_image002[2],1110110.1可以表示為1.1101101*clip_image002[3],任何一個數都的科學計數法表示都為1.xxx*clip_image002[1],尾數部分就可以表示為xxxx,第一位都是1嘛,干嘛還要表示呀?可以將小數點前面的1省略,所以23bit的尾數部分,可以表示的精度卻變成了24bit,道理就是在這里,那24bit能精確到小數點后幾位呢,我們知道9的二進制表示為1001,所以4bit能精確十進制中的1位小數點,24bit就能使float能精確到小數點后6位,而對于指數部分,因為指數可正可負,8位的指數位能表示的指數范圍就應該為:-127-128了,所以指數部分的存儲采用移位存儲,存儲的數據為元數據+127,下面就看看8.25和120.5在內存中真正的存儲方式。

???? 首先看下8.25,用二進制的科學計數法表示為:1.0001*clip_image002[2]

按照上面的存儲方式,符號位為:0,表示為正,指數位為:3+127=130 ,位數部分為,故8.25的存儲方式如下圖所示:

單精度浮點數8.25的存儲方式

而單精度浮點數120.5的存儲方式如下圖所示:

單精度數120.5的存儲方式

那么如果給出內存中一段數據,并且告訴你是單精度存儲的話,你如何知道該數據的十進制數值呢?其實就是對上面的反推過程,比如給出如下內存數據:0100001011101101000000000000,首先我們現將該數據分段,0 10000 0101 110 1101 0000 0000 0000 0000,在內存中的存儲就為下圖所示:

根據我們的計算方式,可以計算出,這樣一組數據表示為:1.1101101*clip_image002[3]=120.5

而雙精度浮點數的存儲和單精度的存儲大同小異,不同的是指數部分和尾數部分的位數。所以這里不再詳細的介紹雙精度的存儲方式了,只將120.5的最后存儲方式圖給出,大家可以仔細想想為何是這樣子的

文本框: 0     100 0000 0101    1101 1010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

下面我就這個基礎知識點來解決一個我們的一個疑惑,請看下面一段程序,注意觀察輸出結果

??????????? float f = 2.2f;
??????????? double d = (double)f;
??????????? Console.WriteLine(d.ToString("0.0000000000000"));
??????????? f = 2.25f;
??????????? d = (double)f;
??????????? Console.WriteLine(d.ToString("0.0000000000000"));

可能輸出的結果讓大家疑惑不解,單精度的2.2轉換為雙精度后,精確到小數點后13位后變為了2.2000000476837,而單精度的2.25轉換為雙精度后,變為了2.2500000000000,為何2.2在轉換后的數值更改了而2.25卻沒有更改呢?很奇怪吧?其實通過上面關于兩種存儲結果的介紹,我們已經大概能找到答案。首先我們看看2.25的單精度存儲方式,很簡單 0 1000 0001 001 0000 0000 0000 0000 0000,而2.25的雙精度表示為:0 100 0000 0001 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000,這樣2.25在進行強制轉換的時候,數值是不會變的,而我們再看看2.2呢,2.2用科學計數法表示應該為:將十進制的小數轉換為二進制的小數的方法為將小數*2,取整數部分,所以0.282=0.4,所以二進制小數第一位為0.4的整數部分0,0.4×2=0.8,第二位為0,0.8*2=1.6,第三位為1,0.6×2 = 1.2,第四位為1,0.2*2=0.4,第五位為0,這樣永遠也不可能乘到=1.0,得到的二進制是一個無限循環的排列 00110011001100110011... ,對于單精度數據來說,尾數只能表示24bit的精度,所以2.2的float存儲為:

單精度數202的存儲方式

但是這樣存儲方式,換算成十進制的值,卻不會是2.2的,應為十進制在轉換為二進制的時候可能會不準確,如2.2,而double類型的數據也存在同樣的問題,所以在浮點數表示中會產生些許的誤差,在單精度轉換為雙精度的時候,也會存在誤差的問題,對于能夠用二進制表示的十進制數據,如2.25,這個誤差就會不存在,所以會出現上面比較奇怪的輸出結果。

本文屬作者原創,只發布在博客園,希望大家在轉載的時候,注明出處和作者,謝謝。


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

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

相關文章

操作系統面試題目詳解

文章目錄1.13 什么是協程?1.14 為什么協程比線程切換的開銷小?1.15 線程和進程的區別?1.16 進程切換為什么比線程更消耗資源?1.17 介紹一下進程之間的通信。1.18 介紹一下信號量。1.19 說說僵尸進程和孤兒進程。1.20 請介紹進程之…

(項目)在線教育平臺(六)

八、授課機構功能 1、模板繼承 如果幾個頁面的大體結構相同,可以使用繼承的方式來實現母版的重用性,也就是子版繼承母版的內容,既可以使用模板的內容,也可以重寫需要改變的地地方。 首先完成授課機構的頁面,通過頁面顯…

C語言 socket 編程學習

對于SOCKET在這里我不想究其歷史,我只想說其時它是一種進程通訊的方式,簡言之就是調用這個網絡庫的一些API函數就能實現分布在不同主機的相關進程之間的數據交換. SOCKET中首先我們要理解如下幾個定義概念: 一是IP地址:IP Address我想很容易理解,就是依照TCP/IP協議分配…

dependency 中的 classifier屬性

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 classifier元素用來幫助定義構件輸出的一些附屬構件。附屬構件與主構件對應,比如主構件是 kimi-app-2.0.0.jar 該項目可能還…

PHP超全局變量$_SERVER

$_SERVER 是一個包含了諸如頭信息(header)、路徑(path)、以及腳本位置(script locations)等等信息的數組。這個數組中的項目由 Web 服務器創建。不能保證每個服務器都提供全部項目;服務器可能會忽略一些,或者提供一些沒有在這里列舉出來的項目。 $_SERVE…

VC讀寫XML文件

1、安裝MSXML 4.0 SP2。在VC6中建立一個基于Dialog的工程。如圖: 在界面上放置3個編輯框、1個按鈕控件。其中屬性設置如下。 編輯框: IDCategoryVariable TypeVariable NameIDC_IDValueCStringm_strIdIDC_AUTHORValueCStringm_strAuthorIDC_TITLEValueCS…

XCode10 swift4.2 適配遇到的坑

以下是2018年10月23日更新 經過大約一個月的時間的適配,項目正式使用XCode10(以下簡稱為10 or XC10)大部分庫都升級為Swift4.2(以下簡稱為 4.2 or S4.2),下面是適配過程中遇到的一些坑。 1. Swift4、Swift4.2混編 如果你對項目是小…

學生管理系統Java版

簡單的學生管理系統 主界面編寫: 1.用輸出語句完成主界面的編寫 2.用Scanner語句實現鍵盤的錄入 3.用swich語句完成操作的選擇 4.用循環完成再次回到主界面 代碼實現: while (true) {//1.用輸出語句完成主界面的編寫System.out.println("--------…

dubbo 配置文件詳解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、dubbo常用配置 <dubbo:service/> 服務配置&#xff0c;用于暴露一個服務&#xff0c;定義服務的元信息&#xff0c;一個服務可…

ASP.NET Core 實戰:Linux 小白的 .NET Core 部署之路

一、前言 最近一段時間自己主要的學習計劃還是按照畢業后設定的計劃&#xff0c;自己一步步的搭建一個前后端分離的 ASP.NET Core 項目&#xff0c;目前也還在繼續學習 Vue 中&#xff0c;雖然中間斷了很長時間&#xff0c;好歹還是堅持下來了&#xff0c;嗯&#xff0c;看了看…

學以致用十三-----Centos7.2+python3+YouCompleteMe成功歷程

歷經幾天的摸索&#xff0c;趟過幾趟坑之后&#xff0c;終于完成YouCompleteMe的安裝配置。 今天同樣是個不能忘記的日子&#xff0c;國恥日&#xff0c;勿忘國恥。&#xff08;9.18&#xff09; 服務器安裝好&#xff0c;基本配置配置好后&#xff0c;開始安裝。 一、檢查服務…

VC畫圖用到的主要方法

1。鼠標落下&#xff0c;記錄鼠標的起始位置 void CMyEasyDrawView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息處理程序代碼和/或調用默認值 //graph->m_nTypedlg-> m_bStartDraw true; m_PtPress m_PtLast point; CView::OnLButtonDown…

【最新版】Java學習路線(含B站口碑推薦視頻鏈接)

文章目錄關于如何自學一、計算機網絡二、數據結構與算法三、操作系統四、計算機組成原理五、編譯原理六、設計模式七、MySQL八、實操工具九、JAVA并發與JVM十、Redis十一、Linux十二、Java路線學習尚硅谷黑馬程序員動力節點狂神說十三、Java基礎十四、JavaWeb十五、框架十六、微…

記錄no static method cannot be reference

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 報錯如題&#xff1a; no static method cannot be reference 我一直以為是在靜態方法中調用了非靜態方法&#xff0c;實際上只是我在注…

文件存儲權限

Android 6.0及以上&#xff0c;需要動態申請權限&#xff1a; Manifest.permission.READ_EXTERNAL_STORAGE Manifest.permission.WRITE_EXTERNAL_STORAGE <uses-permission-sdk-23 android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permis…

從工具的奴隸到工具的主人

摘要&#xff1a;我們每個人都是工具的奴隸。隨著我們的學習&#xff0c;我們不斷的加深自己對工具的認識&#xff0c;從而從它們里面解脫出來。現在我就來說一下我作為各種工具的奴隸&#xff0c;以及逐漸擺脫它們的思想控制的歷史吧。 當我高中畢業進入大學計算機系的時候&am…

記錄A component required a bean named ‘studentService‘ that could not be found.

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 報錯如題&#xff1a; A component required a bean named studentService that could not be found. 出問題的代碼行&#xff1a; &l…

Java---利用程序實現在控制臺聊天

一.普通版&#xff08;不能實現隨意輸入&#xff09; 電腦A(服務器端) package day; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner;public class Mysever {public static void…

16.看板方法——三類改進機會筆記

00.三種常見的模型和它們一些變種&#xff1a;約束理論及其主要理念&#xff1b;還有聚焦于分析和減少變異性的模型及其變種等。 01.五步聚焦法 *a.識別約束 *b.作出決定&#xff0c;以最大化利用約束 *c.使系統中的其余一切部分都服從于b中做出決定 *d.突破約束 *e.避免惰性&a…

C/C++的64位整型

在C/C中&#xff0c;64為整型一直是一種沒有確定規范的數據類型。現今主流的編譯器中&#xff0c;對64為整型的支持也是標準不一&#xff0c;形態各異。一般來說&#xff0c;64位整型的定義方式有long long和__int64兩種(VC還支持_int64)&#xff0c;而輸出到標準輸出方式有pri…