将258.369 double值转为内存表示(科学计数法)

前言

庖丁解牛 - <<庄子>>

庖丁为文惠君解牛,
手之所触, 肩之所倚, 足之所履, 膝之所踦, 砉然向然, 奏刀騞然, 莫不中音, 合于《桑林》之舞, 乃中《经首》之会.

文惠君曰:"嘻, 善哉! 技盍至此乎?"

庖丁释刀对曰:"臣之所好者, 道也, 进乎技矣.
始臣之解牛之时, 所见无非牛者.
三年之后, 未尝见全牛也.
方今之时, 臣以神遇而不以目视, 官知止而神欲行.
依乎天理, 批大郤, 导大窾, 因其固然, 技经肯綮之未尝, 而况大軱乎!
良庖岁更刀, 割也; 族庖月更刀, 折也. 今臣之刀十九年矣, 所解数千牛矣, 而刀刃若新发于硎.
彼节者有间, 而刀刃者无厚;以无厚入有间, 恢恢乎其于游刃必有余地矣!
是以十九年而刀刃若新发于硎.
虽然, 每至于族, 吾见其难为, 怵然为戒, 视为止, 行为迟.
动刀甚微, 謋然已解, 如土委地.
提刀而立, 为之四顾, 为之踌躇满志, 善刀而藏之."

文惠君曰:"善哉, 吾闻庖丁之言, 得养生焉."

测试代码(258.369double值转科学计数法)

/// @file PositiveFloat.cpp
/// @brief 将258.369 double值转为内存表示(科学计数法)

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

int main(int argc, char* argv[]) {
    /// 内存中是小端摆放
    /// 4070,25E0,0000,0000
    unsigned char cBuf[8] = {0x00, 0x00, 0x00, 0x00, 0xe0, 0x25, 0x70, 0x40};
    unsigned short usBuf[4] = {0x0, 0x0, 0x25e0, 0x4070};
    double* pdbl = NULL;

    pdbl = (double*)cBuf;
    printf("%f\n", *pdbl); ///< 258.367188

    pdbl = (double*)usBuf;
    printf("%f\n", *pdbl); ///< 258.367188
    
    return 0;
}

/**
    double值在内存中是8个字节(64bits)
    S = 1bits, (258.369是正数, S = 0)
    E = 11bits
    D = 52bits

    258.369 double值转内存值

    整数部分转2进制表示
    258 / 2
    129         0
    129 / 2
    64          1
    64 / 2
    32          0
    32 / 2
    16          0
    16 / 2
    8           0
    8 / 2
    4           0
    4 / 2
    2           0
    2 / 2
    1           0
    
    整数部分的2进制表示为(从最后一个商念到第一个油余数)
    100000010

    小数部分转2进制表示(最多只算出8位小数的表示)
    0.369 * 2
    0.738           0
    0.738 * 2
    1.476
    0.476           1
    0.476 * 2
    0.952           0
    0.952 * 2
    1.904
    0.904           1
    0.904 * 2
    1.808
    0.808           1
    0.808 * 2
    1.616
    0.616           1
    0.616 * 2
    1.232
    0.232           1
    0.232 * 2
    0.464           0

    小数部分的2进制表示(从第一个进位念到最后一个进位)
    .01011110

    整数 + 小数部分为
    100000010.01011110 * 2^0
    1.0000001001011110 * 2^8
    D = 0000001001011110 (不算整数部分的1)

    E = 1023 + 8 (2^8的指数值)
      = 1031
      = 100,0000,0111
      = 10000000111

    E值的2进制表示
    1031 / 2
    515         1
    515 / 2
    257         1
    257 / 2
    128         1
    128 / 2
    64          0
    64 / 2
    32          0
    32 / 2
    16          0
    16 / 2
    8           0
    8 / 2
    4           0
    4 / 2
    2           0
    2 / 2
    1           0

    从最后一个商念到第一个余数
    100,0000,0111

    拼装SED
    0,10000000111,0000001001011110

    补齐D部分的0(52-16 = 36, 要补36个0)
    0,10000000111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000

    最后的拼装结果
    0100000001110000001001011110000000000000000000000000000000000000

    将拼装结果变成16进制
    0100,0000,0111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000
    4    0    7    0    2    5    E    0    0    0    0    0    0    0    0    0
    407025E000000000
    4070,25E0,0000,0000

    16进制对照表
    0000 = 0 0001 = 1 0010 = 2 0011 = 3
    0100 = 4 0101 = 5 0110 = 6 0111 = 7
    1000 = 8 1001 = 9 1010 = A 1011 = B
    1100 = C 1101 = D 1110 = E 1111 = F
*/

测试代码(-258.369double值转科学计数法)

/// @file PositiveFloat.cpp
/// @brief 将-258.369 double值转为内存表示(科学计数法)

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

int main(int argc, char* argv[]) {
    /// 内存中是小端摆放
    /// C070,25E0,0000,0000
    unsigned char cBuf[8] = {0x00, 0x00, 0x00, 0x00, 0xe0, 0x25, 0x70, 0xC0};
    unsigned short usBuf[4] = {0x0, 0x0, 0x25e0, 0xC070};
    double* pdbl = NULL;

    pdbl = (double*)cBuf;
    printf("%f\n", *pdbl); ///< -258.367188

    pdbl = (double*)usBuf;
    printf("%f\n", *pdbl); ///< -258.367188
    
    return 0;
}

/**
    double值在内存中是8个字节(64bits)
    S = 1bits, (-258.369是负数, S = 1)
    E = 11bits
    D = 52bits

    258.369 double值转内存值

    整数部分转2进制表示
    258 / 2
    129         0
    129 / 2
    64          1
    64 / 2
    32          0
    32 / 2
    16          0
    16 / 2
    8           0
    8 / 2
    4           0
    4 / 2
    2           0
    2 / 2
    1           0
    
    整数部分的2进制表示为(从最后一个商念到第一个油余数)
    100000010

    小数部分转2进制表示(最多只算出8位小数的表示)
    0.369 * 2
    0.738           0
    0.738 * 2
    1.476
    0.476           1
    0.476 * 2
    0.952           0
    0.952 * 2
    1.904
    0.904           1
    0.904 * 2
    1.808
    0.808           1
    0.808 * 2
    1.616
    0.616           1
    0.616 * 2
    1.232
    0.232           1
    0.232 * 2
    0.464           0

    小数部分的2进制表示(从第一个进位念到最后一个进位)
    .01011110

    整数 + 小数部分为
    100000010.01011110 * 2^0
    1.0000001001011110 * 2^8
    D = 0000001001011110 (不算整数部分的1)

    E = 1023 + 8 (2^8的指数值)
      = 1031
      = 100,0000,0111
      = 10000000111

    E值的2进制表示
    1031 / 2
    515         1
    515 / 2
    257         1
    257 / 2
    128         1
    128 / 2
    64          0
    64 / 2
    32          0
    32 / 2
    16          0
    16 / 2
    8           0
    8 / 2
    4           0
    4 / 2
    2           0
    2 / 2
    1           0

    从最后一个商念到第一个余数
    100,0000,0111

    拼装SED
    1,10000000111,0000001001011110

    补齐D部分的0(52-16 = 36, 要补36个0)
    1,10000000111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000

    最后的拼装结果
    1100000001110000001001011110000000000000000000000000000000000000

    将拼装结果变成16进制
    1100,0000,0111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000
    C    0    7    0    2    5    E    0    0    0    0    0    0    0    0    0
    C07025E000000000
    C070,25E0,0000,0000

    16进制对照表
    0000 = 0 0001 = 1 0010 = 2 0011 = 3
    0100 = 4 0101 = 5 0110 = 6 0111 = 7
    1000 = 8 1001 = 9 1010 = A 1011 = B
    1100 = C 1101 = D 1110 = E 1111 = F
*/





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值