将浮点数1864.78转换为二进制和IEEE格式 [英] Convert floating point number 1864.78 to binary and IEEE format

查看:121
本文介绍了将浮点数1864.78转换为二进制和IEEE格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试将标准普尔500的值(今天是1864.78)转换为在内存中以IEEE单精度格式表示的方式.

I've been trying to convert the value of the S&P 500 which today is 1864.78 to how it would be represented in IEEE single precision format in memory.

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

Converting the left of the decimal (1864) is easy.

11101001000.

11101001000.

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

But how do I get the binary representation of the decimal (.78)? I tried using the technique but it produces many numbers over the 8 bit exponent IEEE format:

.78 * 2 = 1.56 1

.78*2=1.56 1

.56 * 2 = 1.12 1

.56*2=1.12 1

.12 * 2 = .24 0

.12*2=.24 0

.24 * 2 = .48 0

.24*2=.48 0

.48 * 2 = .96 0

.48*2=.96 0

.96 * 2 = 1.92 1

.96*2=1.92 1

.92 * 2 = 1.84 1

.92*2=1.84 1

.84 * 2 = 1.68 1

.84*2=1.68 1

.68 * 2 = 1.36 1

.68*2=1.36 1

.36 * 2 = .72 0

.36*2=.72 0

.72 * 2 = 1.44 1

.72*2=1.44 1

.44 * 2 = .88 1(四舍五入是因为我们现在有23位)

.44*2=.88 1 (rounded up because now we have 23 total bits)

11101001000.110001111011 =尾数23位

11101001000.110001111011 = 23 bits for mantissa

添加0作为符号

0 11101001000.110001111011

0 11101001000.110001111011

现在我需要将小数点移到10位以上

Now I need to move the decimal over 10 places

1.1101001000110001111011 x 2 ^ 10的指数现在是10

1.1101001000110001111011 x 2^10 exponent is 10 now

添加0位以使完整尾数为23位

add a 0 bit to make full mantissa 23 bits

1.11010010001100011110110

1.11010010001100011110110

指数是10,所以10 + 127 = 137

exponent is 10 so 10 + 127 = 137

等于10001001

which is equal to 10001001

所以0 10001001 11010010001100011110110是32位数字.

so 0 10001001 11010010001100011110110 which is a 32 bit number.

这看起来像是一个体面的方法吗?我测试了价值,然后写下了这个问题,实际上我自己就能解决这个问题.

Does this look like a decent approach? I tested the value and writing this question I was actually able to work through it on my own.

以此测试十进制FP. http://www.h-schmidt.net/FloatConverter/IEEE754.html

Testing the decimal FP with this. http://www.h-schmidt.net/FloatConverter/IEEE754.html

推荐答案

您有两种不同的转换例程,可以将整数和小数部分转换为二进制.您了解如何将1864转换为二进制,但是在将.78转换为二进制时遇到了问题. 注意:您必须将存储在内存中的实际分数转换为浮点数1864.780.780029 not 0.78.这似乎是您四舍五入"混乱的根源所在.

You have two different conversion routines for converting the integer and fractional parts to binary. You understand how to convert 1864 to binary, but you have problems converting .78 to binary. Note: you must convert the actual fraction held in memory for the float 1864.78 which is 1864.780029 or fraction 0.780029 not 0.78. That appears where your "rounding" confusion is coming from.

要将小数转换为二进制表示,请将小数乘以2,如果结果数的整数部分大于1,则该位的二进制表示为1,否则返回1.表示形式为0.如果大于1,则从数字中减去1并重复进行,直到用完数字或达到所讨论的精度极限为止.例如:

To convert a fraction to its binary representation, you will multiply the fraction by 2 and if the resulting number has an integer part greater than 1, your binary representation of that bit is 1, if not your representation is 0. If greater than one, you subtract 1 from the number and repeat until you have exhausted the number or reached the limit of precision in question. For example:

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'

注意:浮点数小数值趋向于零而不是达到位数限制的趋势.如果您尝试转换0.78(不能将其精确表示为32位浮点值中的小数部分转换为1864.78),您将在第12位获得不同的转换.

note: how the floating-point fractional value will tend to zero rather than reaching your limit of digits. If you attempt to convert 0.78 (which is not capable of exact representation as the fraction to 1864.78 in a 32-bit floating point value) you will reach a different conversion in the 12th bit.

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

Once you have converted your fractional part to binary, you can continue with conversion into IEEE-754 single precision format. e.g.:

decimal  : 11101001000
fraction : 110001111011
sign bit : 0

有偏指数的归一化为:

 11101001000.110001111011  =>  1.1101001000110001111011

     exponent bias: 10
 unbiased exponent: 127
 __________________+____

   biased exponent: 137
   binary exponent: 10001001

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

Conversion to 'hidden bit' format to form mantissa:

1.1101001000110001111011  =>  1101001000110001111011

然后使用符号位 + 多余的127指数 + 尾数形成IEEE-754单精度表示形式:

Then use the sign bit + excess 127 exponent + mantissa to form the IEEE-754 single precision representation:

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                   |

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

Look it over and let me know if you have further questions. If you wanted a simple routine to fill a character array with the resulting conversion, you could do something similar to the following to convert a floating point fraction part to binary:

#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;
}

这篇关于将浮点数1864.78转换为二进制和IEEE格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆