Convert the following single-precision IEEE 754...

// IEEE float format:
//                      sign    exponent    fraction    bias
//  single precision    1[31]   8[30-23]    23[22-00]   127
//  double precision    1[63]   11[62-52]   52[51-00]   1023
// 


// Convert the following single-precision IEEE 754 number into
// a floating-point decimal value.
//
//  1 10000001 10110011001100110011010
//
// first, put the bits in three groups.
//  Bit 31(the leftmost bit) show the sing of the number.
//  Bits 23-30(the next 8 bits) are the exponent.(指数).
//  Bits 0-22(on the right) give the fraction.(分数).
//  single-precision bias is 127.
// second, look at the sign bit.
//  If this bit is a 1, the number is negative.
//  If it is 0, the number is positive.
//  This bit is 1, so the number is negative.
// Get the exponent and the correct bias.
//  The exponent is simply a positive binary number.
//  10000001bin = 129ten
//  Remember that we will have to subtract a bias from this exponent
//  to find the power of 2. Since this is a single-precision number,
//  the bias (偏差) is 127.
// Convert the fraction string into base ten.
//  This is the trickiest step. The binary string represents a fraction,
//  so conversion is a little different.
//  Binary fractions look like this:
//  0.1 = (1/2) = 2^-1
//  0.01 = (1/4) = 2^-2
//  0.001 = (1/8) = 2^-3
//  So, for this example, we multiply each digit by the corresponding
//  power of 2:
//  0.10110011001100110011010bin=1*2^-1 + 0*2^-2 + 1*2^-3 + ...
//      = 1/2+1/8+1/16+...
//  Note that this number is just an approximation on some decimal 
//  number. There will most likely be some error. In this case, the
//  fraction is about 0.7000000476837158.
// This is all the information we need. We can put these numbers in 
// the expression:
// (-1)^sign bit * (1+fraction) * 2^(exponent-bias)
// = (-1)^1 * (1.7000000476837158) * 2^(129-127)
// = -6.8
// The answer is approximately -6.8.
//
// over.


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

// v - value that will be packed.
// size - width
// fsize - precision width
int f2i(float v, int size, int fsize)
{
    char* buf, *p;
    int ret;
    buf = (char*)malloc(sizeof(char)*(size+2));
    /* 
     * 动态设置宽度/精度
     *
     * 在许多时候,我们或许还希望这些格式控制符中用以指定长度信
     * 息的数字是动态的,而不是静态指定的,因为许多时候,程序要
     * 到运行时才会清楚到底需要取字符数组中的几个字符,这种动态
     * 的宽度/精度设置功能在sprintf 的实现中也被考虑到了,
     * sprintf 采用”*”来占用一个本来需要一个指定宽度或精度的常数
     * 数字的位置,同样,而实际的宽度或精度就可以和其它被打印的
     * 变量一样被提供出来,于是,可以变成:
     *   sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
     *   或者:
     *   sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
     */
    // 利用IEEE float的内部实现来pack 浮点数
    sprintf(buf, "%*.*f", size, fsize, v);
    printf("%s\n", buf);
    p = strchr(buf, '.');
    while(*p = *(p+1))
        p++;
    ret = atoi(buf);
    free(buf);
    return ret;
}


int main(int argc, char* argv[])
{
    float val = 1234.4567;
    int i = f2i(val, 8, 8);
    cout << "f2i: " << i << endl;
    return 0;
}

转载于:https://my.oschina.net/qihh/blog/94089

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值