double转bit,根据IEEE标准
作者:互联网
编写软件vscode+gcc,英文名字乱起的,但每一步都对应着标准来着
#include <iostream> #include <math.h> using namespace std; struct DoubleBinary64{ int iExponentLen = 11, iMantissaLen = 52, iDoubleBinLen = iMantissaLen+iExponentLen+1,iExponentsRange=(1<<(iExponentLen-1))-1; }; typedef long long HASH; void GetDoubleBin(char *binArr, double dbNum, DoubleBinary64& dbSt); int GetMantissaBit(char *cArr, double dNum,int iMantissaLen); void GetDecBit(char *ret, int num, int loop); void GetDoubleBin(char *binArr, double dbNum, DoubleBinary64& dbSt) { if (dbNum == 0) { for (int i = 0; i < dbSt.iDoubleBinLen; i++) { binArr[i] = '0'; } return; } int ePath = (int)dbNum, iCount = 0, iMark = 0, iExponentLen = dbSt.iExponentLen , iMantissaLen = dbSt.iMantissaLen, iDoubleBinLen = dbSt.iDoubleBinLen,iExponentsRange=dbSt.iExponentsRange; char *fArr, *finArr; char fExponentArr[iExponentLen+1] = {0}, fMantissa[iMantissaLen+1] = {0}, finMantissa[iMantissaLen+1] = {0}; //循环不能break; 否则无法输出string.函数不能返回指针,否则会被系统回收指针内的内容 if (ePath > 0) { while (true) { if (ePath < 1) { break; } ePath = ePath >> 1; ++iCount; } if (iCount != 0) { char fArr2[iCount + 1] = {0}; fArr = fArr2; ePath = (int)dbNum; for (int i = 0; i <= iCount; i++) { if (ePath <= 0) { fArr[i] = '0'; continue; } int dnum = 1 << (iCount - i); if (dnum > ePath) { fArr[i] = '0'; } else { if (iMark == 0) { iMark = iCount - i; } fArr[i] = '1'; ePath = ePath - dnum; } } iMark = iExponentsRange + iMark; GetDecBit(fExponentArr, iMark, iExponentLen); GetMantissaBit(fMantissa, dbNum,iMantissaLen); iMark = iMark - iExponentsRange; for (int i = 0; i < iMark; i++) { finMantissa[i] = fArr[iCount - iMark + i + 1]; } for (int i = 0; i < iMantissaLen; i++) { if (iMark + i >= iMantissaLen) { break; } finMantissa[iMark + i] = fMantissa[i]; } } } else { iMark = GetMantissaBit(fMantissa, dbNum,iMantissaLen); iMark = iExponentsRange - iMark; GetDecBit(fExponentArr, iMark, iExponentLen); iMark = iExponentsRange - iMark; for (int i = 0; i < iMantissaLen; i++) { if (iMark + i >= iMantissaLen) { finMantissa[i] = '0'; } else { finMantissa[i] = fMantissa[iMark + i]; } } } if (dbNum > 0) { binArr[0] = '0'; } else { binArr[0] = '1'; } for (int i = 0; i < iExponentLen; i++) { binArr[1 + i] = fExponentArr[i]; } for (int i = 0; i < iMantissaLen; i++) { binArr[12 + i] = finMantissa[i]; } } HASH GetDoubleHashByBin(char *binArr,DoubleBinary64& dbSt) { //正向输出string,反向计算数值 HASH dbHash = 0; for (int i = dbSt.iDoubleBinLen-1; i != 0; i--) { char c = binArr[i]; if (c == '1') { dbHash += (1LL << (63 - i)); } } return dbHash; } //获取十进制bit,loop表示bit位数,decNum过大时loop位数会溢出 void GetDecBit(char *ret, int decNum, int loop) { for (int i = 0; i < loop; i++) { if (decNum <= 0) { ret[i] = '0'; continue; } int iSub = 1 << (loop - 1 - i); if (iSub > decNum) { ret[i] = '0'; } else { ret[i] = '1'; decNum = decNum - iSub; } } } //获取double在IEEE中规定的尾数bit,返回值为fraction标记 int GetMantissaBit(char *cArr, double dNum,int iMantissaLen) { double dd = dNum - (int)dNum; int iMark = 0; for (int i = 0; i < iMantissaLen; i++) { if (dd <= 0) { cArr[i] = '0'; continue; } double dbpow = pow(2, -(i + 1)); if (dbpow > dd) { cArr[i] = '0'; } else { if (iMark == 0) { iMark = i + 1; if (iMark >= 52) { iMark = 51; } } cArr[i] = '1'; dd = dd - dbpow; } } if (dNum > 1) { return 0; } return iMark; } int main() { double dbTest=55.68756; DoubleBinary64 dbSt; char dbBinArr[dbSt.iDoubleBinLen+1] = {0}; GetDoubleBin(dbBinArr, dbTest,dbSt); HASH dbBin2Hash = GetDoubleHashByBin(dbBinArr,dbSt); cout << dbBin2Hash << endl; }
输出:4633034144636536021
计算机内存中的值:4633034144636536021
string输出:0100000001001011110110000000000111110111010100010000010011010101
计算器输出:0100000001001011110110000000000111110111010100010000010011010101
如果可以简化代码,请大佬教下,谢谢
标签:int,double,ePath,++,bit,dbSt,IEEE,iMantissaLen,iMark 来源: https://www.cnblogs.com/phlq123/p/15757187.html