c++ float类型研究

 在C++float数据类型是采用科学计数法来表示的,就像下面这样:

  图片2.jpg

其中S位符号位,占一位的二进制数,1为正,0为负,T为底数,按二进制数存储,占23位,E为指数部分,占8位。结构如下:

Float.jpg

 

float 在内存中是按逆字节的存储的:

c++ float类型研究_第1张图片

其中尾数是这样的形式:1.T1T2T3...T23。转换为十进制的数:

 

图片3.jpg

因为指数可以是负数,c++指数部分按原来的指数加上127得到的结果来存储,所以,从内存的得到的指数部分要减去127才能得到原来的指数。

Float在内存的存储形式可能是下面这样:

struct Float

 {

unsigned base : 23;

unsigned index : 8;

unsigned sign: 1;

 }

并非是下面:

struct Float

 {

unsigned sign: 1;

unsigned index : 8;

unsigned base : 23;

 };

因为float 在内存中是按逆字节的存储的,可以看上面的。

可以用下面的程序来测试:

float f = -10.5f; Float &myf = (Float &)f; cout << "float sign: " << myf.sign << endl; cout << "float index: " << myf.index << endl; cout << "float base: " << myf.base << endl;

结果如下:

1.PNG

先来把10.5转换为二进制数:1010.1转换为科学计数法:1.0101 *2^3,所以尾数部分为:图片4.jpg,对应的十进制数是:2621440.

指数部分为3,加上127后为130

符号位为1,表示为正数。

下面的程序把float数转换为十进制数。

int ArrayDivBy2(int *pArray, int nSize) { div_t dr = {0}; for(int i = 0; i < nSize; ++ i) { pArray[i] += dr.rem * 10; pArray[i] = (dr = div(pArray[i], 2)).quot; } return dr.rem; } void ArrayAdd(int *pArray1, int *pArray2, int nSize) { div_t dr = {0}; for(int i = nSize - 1; i >= 0; i--) { pArray1[i] += dr.quot + pArray2[i]; pArray1[i] = (dr = div(pArray1[i], 10)).rem; } } void ExtractMantissa(float fNum, int *pMantissa) { unsigned char *pData = (unsigned char*)&fNum; memset(pMantissa, 0, 24*sizeof(int)); pMantissa[0] = 1; int aOrder[24] = {0}; aOrder[0] = 1; for(int i = 0; i < 23; i++) { unsigned char temp; temp = pData[2 - (i + 1) / 8]; temp <<= (i + 1)%8; temp >>= 7U; ArrayDivBy2(aOrder, 24); if(1 == temp) ArrayAdd(pMantissa, aOrder, 24); } } int ExtractExponent(float fNum) { unsigned char *pData = (unsigned char *)&fNum; unsigned char temp = pData[3]; temp = temp << 1U ; temp |= pData[2] >> 7U; temp -= 0x7F; return *(char *)&temp; } int ArrayMulti2(int *pArray, int nSize) { div_t dr = {0}; for(int i = nSize - 1; i >= 0; --i) { pArray[i] *= 2; pArray[i] += dr.quot; pArray[i] = (dr = div(pArray[i], 10)).rem; } return dr.quot; } int ArrayDiv2(int *pArray, int nSize) { div_t dr = {0}; for(int i = 0; i < nSize - 1; i++) { pArray[i] += dr.quot; pArray[i] = (dr = div(pArray[i], 2)).rem; } return dr.quot; } int GetDecNum(float fNum, int *pArray) { int aMantissa[24]; ExtractMantissa(fNum, aMantissa); int nExponent = ExtractExponent(fNum); memset(pArray, 0, sizeof(int) * 152); int nStart = 0; if(nExponent > 0) { nStart = 128; memcpy(&pArray[nStart], aMantissa, sizeof(int) * 24); for(int i = 0; i < nExponent; i++) { ArrayMulti2(pArray, 152); } } else { memcpy(&pArray[nStart], aMantissa, sizeof(int) * 24); for(int i = 0; i < abs(nExponent); i++) { ArrayDiv2(pArray,25 + i); } } int nFirst = 0; for(; pArray[nFirst] == 0 && nFirst <= 128; nFirst++); int nExp10 = nStart - nFirst; if(nExp10 != 0 || nExponent > 0) { for(int i = 0; i < 24; i++) { pArray[i] = pArray[i + nFirst]; } } return nExp10; }

你可能感兴趣的:(C++)