您的位置:首页 > 其它

由内存IEEE值还原浮点数原值

2016-01-19 18:06 232 查看
/// @file \exam_ieee_float\main.cpp
/// @brief 已知地址0013ff74,内容为00684544小尾方式, 如果这个地址是float变量,
/// 那么其10进制真值为多少?
/// @note
/// 这道题如果用编码实现, so easy, 都让开, 我来手工算一下^_^

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    /// 解题完成后的验证
    /// 00684544小尾方式是不是787.625
    unsigned char cBuf[4] = {0x00, 0x68, 0x45, 0x44};
    printf("%f\n", *((float*)cBuf)); ///< 789.625000

    /// 解题后感觉 : 如果给我配一个买菜用的计算器^_^
    /// 我100%能准确还原内存中的float值或double值到原始浮点数
    /// 在草稿纸上计算, 还是不能保证没有笔误!
    /// 没过没有考试用的计算器,我想,怎么也得检查3遍吧...
    return 0;
}

/**
float变量, 在内存中为00684544小尾方式, 10进制值的手工计算

  00684544 对应的4个字节内容 变成科学计数法表示为 0x44456800

  0x44456800 变成2进制

  4     4     4     5     6     8     0     0
  0100, 0100, 0100, 0101, 0110, 1000, 0000, 0000
  01000100010001010110100000000000

  分离出SED的值, 对于float值, S = 1, E = 8, D = 23
  0, 10001000, 10001010110100000000000

  去掉D的尾部连续的补充0
  0, 10001000, 100010101101

  分析SED值
  ======================================================================
  S = 0, 正数
  ======================================================================
  E = 10001000 = 指数N = 9
  ----------------------------------------------------------------------
  pow(2, 7) = 2 * 2 * 2 * 2 * 2 * 2 * 2 = 16 * 8 = 128
  10001000 = pow(2, 7) + pow(2, 3) = 128 + 8 = 127 + 9
  浮点数的E值运算 = 127 + N, 所以指数N = 9
  ======================================================================
  D = 100010101101
  假设 float fValue = 1.x * pow(2, n)
  D为1.x的小数部分
  ======================================================================      
  浮点数的还原值 = 1.100010101101B * pow(2, 9)
  ======================================================================
  将浮点值变为不用科学计数法表示的2进制固定浮点值
  2进制固定浮点值 = 1.100010101101B * pow(2, 9)
                    1100010101.101B
  ======================================================================
  浮点原值的整数部分为 1100010101B
  浮点原值的小数部分为 .101B
  ======================================================================
  小数部分进制值    = .101B
                    = 1 * 1/pow(2, 1) + 1 * 1/pow(2, 3)
                    = 1/2 + 1/8
                    = 0.5 + 0.125
                    = 0.625
  ----------------------------------------------------------------------
  整数部分10进制值  = 1100010101B
                    = 1*pow(2,9) + 1*pow(2,8) + 1*pow(2,4) + 1*pow(2,2) 
                        + 1*pow(2,0)
                    = 128*4 + 128*2 + 16 + 4 + 1
                    = 512 + 256 + 21
                    = 512 + 277
                    = 789
  ======================================================================
  还原完成 : 还原的浮点数为 789.625
  ======================================================================
  现在可以编码验证一下,00684544小尾方式是不是789.625 ^_^
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: