1. 程式人生 > >c/c++中的浮點數的表示方法

c/c++中的浮點數的表示方法

轉自:http://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html

任何資料在記憶體中都是以二進位制的形式儲存的,例如一個short型資料1156,其二進位制表示形式為00000100 10000100。則在Intel CPU架構的系統中,存放方式為  10000100(低地址單元) 00000100(高地址單元),因為Intel CPU的架構是小端模式。但是對於浮點數在記憶體是如何儲存的?目前所有的C/C++編譯器都是採用IEEE所制定的標準浮點格式,即二進位制科學表示法。

       在二進位制科學表示法中,S=M*2^N 主要由三部分構成:符號位+階碼(N)+尾數(M)。對於float型資料,其二進位制有32位,其中符號位1位,階碼8位,尾數23位;對於double型資料,其二進位制為64位,符號位1位,階碼11位,尾數52位。

                31        30-23       22-0

float       符號位     階碼        尾數

                63        62-52       51-0

double    符號位     階碼        尾數

符號位:0表示正,1表示負

階碼:這裡階碼採用移碼錶示,對於float型資料其規定偏置量為127,階碼有正有負,對於8位二進位制,則其表示範圍為-128-127,double型規定為1023,其表示範圍為-1024-1023。比如對於float型資料,若階碼的真實值為2,則加上127後為129,其階碼錶示形式為10000010

尾數:有效數字位,即部分二進位制位(小數點後面的二進位制位),因為規定M的整數部分恆為1,所以這個1就不進行儲存了。

下面舉例說明:

float型資料125.5轉換為標準浮點格式

125二進位制表示形式為1111101,小數部分表示為二進位制為 1,則125.5二進位制表示為1111101.1,由於規定尾數的整數部分恆為1,則表示為1.1111011*2^6,階碼為6,加上127為133,則表示為10000101,而對於尾數將整數部分1去掉,為1111011,在其後面補0使其位數達到23位,則為11110110000000000000000

則其二進位制表示形式為

0 10000101 11110110000000000000000,則在記憶體中存放方式為:

00000000   低地址

00000000

11111011

01000010   高地址

而反過來若要根據二進位制形式求算浮點數如0 10000101 11110110000000000000000

由於符號為為0,則為正數。階碼為133-127=6,尾數為11110110000000000000000,則其真實尾數為1.1111011。所以其大小為

1.1111011*2^6,將小數點右移6位,得到1111101.1,而1111101的十進位制為125,0.1的十進位制為1*2^(-1)=0.5,所以其大小為125.5。

同理若將float型資料0.5轉換為二進位制形式

0.5的二進位制形式為0.1,由於規定正數部分必須為1,將小數點右移1位,則為1.0*2^(-1),其階碼為-1+127=126,表示為01111110,而尾數1.0去掉整數部分為0,補齊0到23位00000000000000000000000,則其二進位制表示形式為

0 01111110 00000000000000000000000

由上分析可知float型資料最大表示範圍為1.11111111111111111111111*2^127=3.4*10^38

對於double型資料情況類似,只不過其階碼為11位,偏置量為1023,尾數為52位。

測試程式:

複製程式碼
/*測試浮點型資料在記憶體中存放方式  2011.10.2*/ 

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
float a=125.5;
char *p=(char *)&a;
printf("%d\n",*p);
printf("%d\n",*(p+1));
printf("%d\n",*(p+2));
printf("%d\n",*(p+3));
return 0;
}
複製程式碼

輸出結果為:

0

0

-5

66

在上面已經知道float型125.5在記憶體中存放方式為:

00000000   低地址

00000000

11111011

01000010   高地址

因此對於p和p+1指向的單元,其中儲存的二進位制數表示的十進位制整數為0;

而對於p+2指向的單元,由於為char型指標,為帶符號的資料型別,因此11111011,符號位為1,則為負數,由於在記憶體中二進位制是以補碼儲存的,所以其真值為-5.

對於p+3指向的單元,01000010,為正數,則其大小為66。上面程式輸出結果驗證了其正確性。

相關推薦

C語言點數在內存的存儲方式

大端 部分 由於 包含 指數 類型 計算機 data- trac 關於多字節數據類型在內存中的存儲問題 //////////////////////////////////////////////////////////////// int ,short 各

c語言點數的陷阱

錯誤程式碼: #include <stdio.h> int main(){ double i; for(i = 0.0; i = 10.0; i += 0.1) printf("

1.2 C/C++立即數表示方法

                    20      // 十進位制              &

C語言位操作符(1)-計算機的整數表示方法

寫在前面 長久以來,位操作符一直困擾著我,為什麼呢?因為其雖易用,但是我自己卻理解不透徹,用著總覺得有隱患?那麼今天就來詳細地理一下計算機中的位操作符與整數在計算機中的儲存。 本文是作為一個非科班出身程式設計師的自我學習記錄之作,如果能夠在自我提高的同時也能幫

c++識別符號常量表示方法

什麼是識別符號常量? 識別符號常量又稱符號常量,它是指用一個符號來代替一個數值。 我們為什麼要用它? 對於一個在程式中常常出現的數值,我們可以定義一個符號來表示它。好處是修改方便,程式碼可讀性高。例如,在程式中用到了常數π,如果每次都寫3.141592

IEEE 754——計算機點數表示方法

楔子 #include <iostream> int main(int, char**) { std::cout.precision(20); float a = 123.45678901234567890;

c/c++點數是否為0的判斷

efi bit c++ 部分 符號位 eee 小數 sil code 在c/c++中,因為浮點數在內存中的表示是不精確的,會有很微小的誤差,所以判斷是否為0,就看它的絕對值是不是<=eps。 eps可以看成是epsilon的縮寫,可以用來表示一個無窮小的量,通常取e

Java點數相減造成損失的簡單解決方法

今天遇到個問題:double m1 = 0.09    m1 = m1 - 0.05    結果m1卻不是0.04而是0.039999999999999994! 查資料說是java遵循IEEE754浮點數的運算規範,使用分數與指數表示浮點數 如:0.5

C++學習之點數的整型數次方

點選開啟連結 class Solution { public: double Power(double base, int exponent) { double sum=1.0; if(exponent>0){ for(int i=1;i<

計算機點數表示,IEEE 754標準

IEEE Standard for Floating-Point Arithmetic(IEEE 754,Institute of Electrical and Electronics Engineers)是1985年建立的浮點數計算的技術標準。解決了原來浮點數實現不一致的問題,許多硬體

C#開發常用加密解密方法解析

一、MD5加密演算法 我想這是大家都常聽過的演算法,可能也用的比較多。那麼什麼是MD5演算法呢?MD5全稱是message-digest algorithm 5,簡單的說就是單向的加密,即是說無法根據密文推匯出明文。 MD5主要用途: 1、對一段資訊生成資訊摘要,該摘要對該資訊具有唯一性

C# 類隱藏基類方法和Partial

C# 類中隱藏基類方法和Partial 時間 2014-11-14 11:50:03   薑糖水 原文   http://www.cnphp6.com/archives/60699

機器點數表示

       在初學C語言時,一直體會不到所謂的浮點數容易造成誤差,最近看到一篇關於浮點數的文章,加上現在的學習,對浮點數的內部儲存方式有了更加深入的理解,於是也漸漸理解了浮點數的誤差。         相比int等整型,float等浮點型別的表示和儲存較為複雜,但它又是一

jquery點數運算結果保留兩位小數的方法

今天在偶然用到了一個簡單的運算,38.6-38.2,結果竟然是0.3999999999999986,一般來說肯定是0.4。 通過查詢,瞭解到,計算機內部的二進位制是無法精確表達0.1,0.2之類的數字的。 原理: 像簡單的0.1 用十進位制表示:1×10^-1 ,也就是0.1 而用二進位制表

Unity 3D:訪問另一個C#類的屬性或方法

在開發Unity 3D 遊戲的過程中,經常遇到在某個C#類中訪問另一個C#類中的方法或屬性;比如:在Eenmy.cs中訪問PlayAttack.cs指令碼中的TakeDamage(int damage

C語言運算子優先順序記憶方法

  C語言中有很多運算子,它們之間有優先順序關係,但是原來苦於優先順序關係太多,根本記不住,所以程式設計時只能不斷的用括號來組合程式碼~   今天找到了一個口訣,在這裡記下來,方便以後查閱 圓方

使用 C++ bitset 操縱點數型別(float、double)

#include <bitset> bitset 類是將資料轉換為二進位制位(遵循 IEEE 754 的儲存和表示方法,關於 IEEE 754 更多更全的使用方法和原理請見 IEEE 754——計算機中浮點數的表示方法 )。 如下: #in

c語言點運算的inf和nan錯誤

============================================ 作者:yuanlulu http://blog.csdn.net/yuanlulu 版權沒有,但是轉載請保留此段宣告 ===============================

java 點數表示詳解及解決方法(例項函式)

定點數表達法的缺點在於其形式過於僵硬,固定的小數點位置決定了固定位數的整數部分和小數部分,不利於同時表達特別大的數或者特別小的數。 計算機系統採納了所謂的浮點數表達方式。這種表達方式利用科學計數法來表達實數,即用一個尾數(Mantissa也叫有效數字 ),一個基數(Base

計算機記憶體點數表示

浮點概念的引入 在計算機系統的發展過程中,曾經提出過多種方法表達實數。比如定點數表示法, 這種表示方法將小數點的位置固定在某一個位置,比如: 11001000.00110001,這個16位(2位元組) 的定點數用前面8位表示整數部分,後面8位表示小數部分,這種