我有一些不明白如何逐步将int转换为浮动?假设我有一个二进制格式的带符号整数.而且,我想把它用手漂浮.但是,我不能.因此,CAn一个人告诉我如何逐步进行转换?
我在c中进行多次转换?喜欢;
int a = foo ( );
float f = ( float ) a ;
Run Code Online (Sandbox Code Playgroud)
但是,我还没弄清楚背景会发生什么.而且,为了更好地理解,我想手工完成转换.
编辑:如果你对转换了解很多,你也可以提供有关浮动到双转换的信息.而且,对于float到int
pax*_*blo 15
浮点值(IEEE754,无论如何)基本上有三个组成部分:
s;e; 和m.精度决定了指数和尾数有多少位可用.让我们检查单精度浮点的值0.1:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 1/n
0 01111011 10011001100110011001101
||||||||||||||||||||||+- 8388608
|||||||||||||||||||||+-- 4194304
||||||||||||||||||||+--- 2097152
|||||||||||||||||||+---- 1048576
||||||||||||||||||+----- 524288
|||||||||||||||||+------ 262144
||||||||||||||||+------- 131072
|||||||||||||||+-------- 65536
||||||||||||||+--------- 32768
|||||||||||||+---------- 16384
||||||||||||+----------- 8192
|||||||||||+------------ 4096
||||||||||+------------- 2048
|||||||||+-------------- 1024
||||||||+--------------- 512
|||||||+---------------- 256
||||||+----------------- 128
|||||+------------------ 64
||||+------------------- 32
|||+-------------------- 16
||+--------------------- 8
|+---------------------- 4
+----------------------- 2
Run Code Online (Sandbox Code Playgroud)
标志是积极的,这很容易.
指数是64+32+16+8+2+1 = 123 - 127 bias = -4,所以乘数是2 -4或1/16.偏见是存在的,这样你就可以获得非常小的数字(如10 -30)以及大数字.
尾数很粗糙.它由1(隐式碱)加(用于与每个值1 /(2所有那些比特Ñ)如n在开始1和向右增加), {1/2, 1/16, 1/32, 1/256, 1/512, 1/4096, 1/8192, 1/65536, 1/131072, 1/1048576, 1/2097152, 1/8388608}.
当你添加所有这些,你得到1.60000002384185791015625.
当你乘以2 -4乘数时,你会得到0.100000001490116119384765625,这就是为什么他们说你不能完全代表0.1IEEE754浮点数.
在将整数转换为浮点数方面,如果尾数中包含尽可能多的位(包括隐式1),则只需传输整数位模式并选择正确的指数即可.不会有精度损失.例如,双精度IEEE754(64位,其中52/53为尾数)对32位整数没有任何问题.
如果整数中有更多位(例如32位整数和32位单精度浮点数,只有23/24位尾数),则需要缩放整数.
这涉及剥离最低有效位(实际舍入),以使其适合尾数位.这当然会导致精度损失,但这是不可避免的.
我们来看一个具体的值,123456789.以下程序转储每种数据类型的位.
#include <stdio.h>
static void dumpBits (char *desc, unsigned char *addr, size_t sz) {
unsigned char mask;
printf ("%s:\n ", desc);
while (sz-- != 0) {
putchar (' ');
for (mask = 0x80; mask > 0; mask >>= 1, addr++)
if (((addr[sz]) & mask) == 0)
putchar ('0');
else
putchar ('1');
}
putchar ('\n');
}
int main (void) {
int intNum = 123456789;
float fltNum = intNum;
double dblNum = intNum;
printf ("%d %f %f\n",intNum, fltNum, dblNum);
dumpBits ("Integer", (unsigned char *)(&intNum), sizeof (int));
dumpBits ("Float", (unsigned char *)(&fltNum), sizeof (float));
dumpBits ("Double", (unsigned char *)(&dblNum), sizeof (double));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我系统的输出如下:
123456789 123456792.000000 123456789.000000
integer:
00000111 01011011 11001101 00010101
float:
01001100 11101011 01111001 10100011
double:
01000001 10011101 01101111 00110100 01010100 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
我们将一次看一下这些.首先是整数,简单的两个幂:
00000111 01011011 11001101 00010101
||| | || || || || | | | +-> 1
||| | || || || || | | +---> 4
||| | || || || || | +-----> 16
||| | || || || || +----------> 256
||| | || || || |+------------> 1024
||| | || || || +-------------> 2048
||| | || || |+----------------> 16384
||| | || || +-----------------> 32768
||| | || |+-------------------> 65536
||| | || +--------------------> 131072
||| | |+----------------------> 524288
||| | +-----------------------> 1048576
||| +-------------------------> 4194304
||+----------------------------> 16777216
|+-----------------------------> 33554432
+------------------------------> 67108864
==========
123456789
Run Code Online (Sandbox Code Playgroud)
现在让我们看一下单精度浮点数.注意尾数匹配整数的位模式为近似完美匹配:
mantissa: 11 01011011 11001101 00011 (spaced out).
integer: 00000111 01011011 11001101 00010101 (untouched).
Run Code Online (Sandbox Code Playgroud)
在尾数的左边有一个隐含的 1位,它也在另一端被舍入,这是精度损失的来源(从上面的程序输出中的值123456789变为123456792as).
制定价值观:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 1/n
0 10011001 11010110111100110100011
|| | || |||| || | |+- 8388608
|| | || |||| || | +-- 4194304
|| | || |||| || +------ 262144
|| | || |||| |+-------- 65536
|| | || |||| +--------- 32768
|| | || |||+------------ 4096
|| | || ||+------------- 2048
|| | || |+-------------- 1024
|| | || +--------------- 512
|| | |+----------------- 128
|| | +------------------ 64
|| +-------------------- 16
|+---------------------- 4
+----------------------- 2
Run Code Online (Sandbox Code Playgroud)
标志是积极的.指数是128+16+8+1 = 153 - 127 bias = 26,所以乘数是2 26或67108864.
尾数1(隐式碱)加(如上所述), {1/2, 1/4, 1/16, 1/64, 1/128, 1/512, 1/1024, 1/2048, 1/4096, 1/32768, 1/65536, 1/262144, 1/4194304, 1/8388608}.当你添加所有这些,你得到1.83964955806732177734375.
当你乘以2 26乘数时,你会得到123456792,与程序输出相同.
双位掩码输出是:
s eeeeeeeeeee mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
0 10000011001 1101011011110011010001010100000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
我不打算通过找出那个野兽的价值的过程:-)但是,我将在整数格式旁边显示尾数以显示公共位表示:
mantissa: 11 01011011 11001101 00010101 000...000 (spaced out).
integer: 00000111 01011011 11001101 00010101 (untouched).
Run Code Online (Sandbox Code Playgroud)
您可以再次看到左侧隐含位的共性和右侧的更大位可用性,这就是为什么在这种情况下不会丢失精度的原因.
在浮点数和双打数之间的转换方面,这也很容易理解.
首先必须检查特殊值,如NaN和无穷大.这些由特殊的指数/尾数组合表示,并且可能更容易检测到这些前置角,以新格式生成等效物.
那么在你从double到float的情况下,你显然可用的范围较小,因为指数中的位数较少.如果你的双精度超出浮动范围,你需要处理它.
假设它适合,那么你需要: