将浮点数1864.78转换为二进制和IEEE格式

Kan*_*man 0 c floating-point binary ieee-754

我一直在努力将标准普尔500指数的价值(现在是1864.78)转换为它在内存中以IEEE单精度格式表示的价值.

转换小数点左边(1864)很容易.

11101001000.

但是如何获得十进制的二进制表示(.78)?我尝试使用该技术但它在8位指数IEEE格式上产生了许多数字:

.78*2 = 1.56 1

.56*2 = 1.12 1

.12*2 = .24 0

.24*2 = .48 0

.48*2 = .96 0

.96*2 = 1.92 1

.92*2 = 1.84 1

.84*2 = 1.68 1

.68*2 = 1.36 1

.36*2 = .72 0

.72*2 = 1.44 1

.44*2 = .88 1(向上舍入,因为现在我们总共有23位)

11101001000.110001111011 =尾数23位

添加0表示符号

0 11101001000.110001111011

现在我需要将小数移动10个以上

1.1101001000110001111011 x 2 ^ 10指数现在是10

添加0位以使全尾数为23位

1.11010010001100011110110

指数是10所以10 + 127 = 137

等于10001001

所以0 10001001 11010010001100011110110是32位数.

这看起来像是一个体面的方法吗?我测试了这个值并写下了这个问题,我实际上可以自己完成它.

用这个测试十进制FP. http://www.h-schmidt.net/FloatConverter/IEEE754.html

Dav*_*ica 8

您有两个不同的转换例程,用于将整数和小数部分转换为二进制.您了解如何转换1864为二进制文件,但转换.78为二进制文件时遇到问题.注意:您必须转换举办的实际分数内存浮子1864.781864.780029或部分0.780029 0.78.这似乎是你的"四舍五入"混乱的来源.

要将分数转换为其二进制表示,您将乘以分数2,如果结果数的整数部分大于,则1该位的二进制表示1,如果不是您的表示0.如果大于1,1则从数字中减去并重复,直到数字耗尽或达到相关精度限制为止.例如:

number   : 1864.78
float    : 1864.780029  (actual nearest representation in memory)
integer  : 1864
fraction : 0.780029

 2 * 0.780029 = 1.560059  =>  integer part (1) fraction (0.560059)  =>  '1'
 2 * 0.560059 = 1.120117  =>  integer part (1) fraction (0.120117)  =>  '1'
 2 * 0.120117 = 0.240234  =>  integer part (0) fraction (0.240234)  =>  '0'
 2 * 0.240234 = 0.480469  =>  integer part (0) fraction (0.480469)  =>  '0'
 2 * 0.480469 = 0.960938  =>  integer part (0) fraction (0.960938)  =>  '0'
 2 * 0.960938 = 1.921875  =>  integer part (1) fraction (0.921875)  =>  '1'
 2 * 0.921875 = 1.843750  =>  integer part (1) fraction (0.843750)  =>  '1'
 2 * 0.843750 = 1.687500  =>  integer part (1) fraction (0.687500)  =>  '1'
 2 * 0.687500 = 1.375000  =>  integer part (1) fraction (0.375000)  =>  '1'
 2 * 0.375000 = 0.750000  =>  integer part (0) fraction (0.750000)  =>  '0'
 2 * 0.750000 = 1.500000  =>  integer part (1) fraction (0.500000)  =>  '1'
 2 * 0.500000 = 1.000000  =>  integer part (1) fraction (0.000000)  =>  '1'
Run Code Online (Sandbox Code Playgroud)

注意:该怎么浮点分数值将趋于零,而不是达到你的数字限制.如果您尝试转换0.78(无法精确表示为1864.7832位浮点值中的分数),您将在第12位达到不同的转换.

将小数部分转换为二进制后,可以继续转换为IEEE-754单精度格式.例如:

decimal  : 11101001000
fraction : 110001111011
sign bit : 0
Run Code Online (Sandbox Code Playgroud)

偏差指数的归一化是:

 11101001000.110001111011  =>  1.1101001000110001111011

     exponent bias: 10
 unbiased exponent: 127
 __________________+____

   biased exponent: 137
   binary exponent: 10001001
Run Code Online (Sandbox Code Playgroud)

转换为"隐藏位"格式以形成尾数:

1.1101001000110001111011  =>  1101001000110001111011
Run Code Online (Sandbox Code Playgroud)

然后使用符号位 + 超过127指数 + 尾数来形成IEEE-754单精度表示:

IEEE-754 Single Precision Floating Point Representation

  0 1 0 0 0 1 0 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 0 0 1 1 1 1 0 1 1 0
 |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
 |s|      exp      |                  mantissa                   |
Run Code Online (Sandbox Code Playgroud)

仔细看看,如果您有其他问题,请告诉我.如果您想要一个简单的例程来填充带有结果转换的字符数组,您可以执行类似于以下操作的操作,将浮点部分转换为二进制:

#define MANTISSA 23
...

/** return string containing binary representation of fraction
 *  The function takes a float as an argument and computes the
 *  binary representation of the fractional part of the float,
 *  On success, the function returns a null-terminated string
 *  containing the binary value, or NULL otherwise. The conversion
 *  is limited to the length of your MANTISSA (23-bits for single
 *  precission, 52-bits for double precision). You must insure
 *  you provide a buffer for 's' of at least MANTISSA + 1 bytes.
 */
char *fpfrc2bin (char *s, float fvalue)
{
    /* obtain fractional value from fvalue */
    float fv = fvalue > 1.0 ? fvalue - (int)fvalue : fvalue;
    char *p = s;
    unsigned char it = 0;

    while (fv > 0 && it < MANTISSA + 1)
    {   /* convert fraction */
        fv = fv * 2.0;
        *p++ = ((int)fv) ? '1' : '0';
        *p = 0;  /* nul-terminate */
        fv = ((int)fv >= 1) ? fv - 1.0 : fv;
        it++;
    }

    return s;
}
Run Code Online (Sandbox Code Playgroud)