Chinaunix首页 | 论坛 | 博客
  • 博客访问: 232696
  • 博文数量: 39
  • 博客积分: 420
  • 博客等级: 下士
  • 技术积分: 457
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-01 10:22
文章分类

全部博文(39)

文章存档

2015年(15)

2014年(11)

2013年(1)

2012年(2)

2011年(1)

2010年(9)

我的朋友

分类: C/C++

2015-04-08 11:25:10

首先要理解十六进制在内存中保存的形式,如下:
double在内存中是以八个字节保存的,即64bit,那么最高一位表示符号位,中间11位为阶码,那么最后52位则是尾数。
如:125.12在内存保存的形式为:48 E1 7A 14 AE 47 5F 40

这是低位在前,高位在后:48 E1 7A 14 AE 47 5F 40
高位在前,低位在后则是:40 5F 47 AE 14 7A E1 48
转换成2进制则是:0           10000000101     1111010001111010111000010100011110101110000101001000
                          符号位     阶码                  尾数即底数

  从而知道该数为正数,符号位为0表示正数,1表示负数
  指数为阶码减去1023,10000000101的十进制为:1029,指数=1029-1023=6
  1 111101   0001111010111000010100011110101110000101001000,在从底数算起时,要多加一个1
  整数  1.0/(0*2^1)+1.0/(0*2^2)+1.0/(0*2^3)+1.0/(1*2^4)+1.0/(1*2^5)+1.0/(1*2^6)+1.0/(1*2^7)+...
  前的1是手动加上去的
  最后得整数为125,小数为:0.120000

相应的c++代码:

点击(此处)折叠或打开

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <stdio.h>
  4. #include <iomanip>
  5. using namespace std;
  6. typedef struct tag_stTA        // 实时数据
  7. {        
  8.     double    fValue;            //对应系统中数据对象的状态
  9. }TA;
  10. long long int getS(int e,int m)
  11. {
  12.     long long int s=e;
  13.     for (int i=1;i<m;i++)
  14.     {
  15.         s*=e;
  16.     }
  17.     return s;
  18. }
  19. int _tmain(int argc, _TCHAR* argv[])
  20. {
  21.     TA ta;
  22.     BYTE p[8];
  23.     int sz = sizeof(TA);
  24.     ta.fValue=-6034578415500000.12;
  25.     memcpy((BYTE *)p,&ta, sz);
  26.     printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
  27.     long long int a=0x0000000000000000;
  28.     a=a|p[7];
  29.     a=(a<<8)|p[6];
  30.     a=(a<<8)|p[5];
  31.     a=(a<<8)|p[4];
  32.     a=(a<<8)|p[3];
  33.     a=(a<<8)|p[2];
  34.     a=(a<<8)|p[1];
  35.     a=(a<<8)|p[0];
  36.     int s=(a>>63)&0xFF;//获得符号位,1表示负数,0表示正数
  37.     int e=(a>>52)&0x7FF;
  38.     e=e-1023;//获得指数
  39.     long long int m=a&0xFFFFFFFFFFFFF|0x10000000000000;//获得底数
  40.     //cout<<setiosflags(ios::uppercase)<<hex<<m<<endl;
  41.     long long int c=0;
  42.     double v=0.0,y=1.0;
  43.     if (e>=0)//向右移动
  44.     {
  45.         c=(m>>(52-e))&0xFFFFFFFFFFFFFFFF;//获得整数的二进制
  46.         long long int b=0;
  47.         for (int i=0;i<52-e;i++)
  48.         {
  49.             b=(b<<1)|0x01;
  50.         }
  51.         b=b&m;//获得小数的二进制
  52.         int j=0;
  53.         for (int i=52-e-1;i>=0;i--)
  54.         {
  55.             j++;
  56.             y=(double)(((b>>i)&0x01)*getS(2,j));
  57.             if (y>0.0)
  58.             {
  59.                 v+=1.0/y;
  60.             }
  61.         }
  62.         v=c+v;
  63.         if (s>0)
  64.         {
  65.             v=-v;
  66.         }
  67.     }
  68.     else//向左移动
  69.     {
  70.         e=-e;
  71.         c=m;
  72.         int j=0;
  73.         for (int i=52+e-1;i>=0;i--)
  74.         {
  75.             j++;
  76.             y=(float)(((c>>i)&0x01)*getS(2,j));
  77.             if (y>0.0)
  78.             {
  79.                 v+=1.0/y;
  80.             }
  81.         }
  82.         if (s>0)
  83.         {
  84.             v=-v;
  85.         }
  86.     }
  87.     printf("%.2f\n",v);
  88.     return 0;
  89. }


阅读(8364) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~