简体   繁体   English

为什么在生成的程序集中将C代码中的1.0f表示为1065353216?

[英]Why is 1.0f in C code represented as 1065353216 in the generated assembly?

In CI have this code block: 在CI中有以下代码块:

if(x==1){
    a[j][i]=1;
}
else{
    a[j][i]=0;
}

a is a matrix of float values, if I try to see the compiled assembly of this code in nasm syntax a是浮点值的矩阵,如果我尝试看到NASM语法编译该代码的组件

the line a[j][i]=0; 线a[j][i]=0; assignment, was coded in this way 作业是用这种方式编码的

dword [rsi+rdi], 0

but the line a[j][i]=1; 但是行a[j][i]=1; assignment, was coded in this way 作业是用这种方式编码的

dword [rsi+rdi], 1065353216

How can 1065353216 represent a 1.0f ?? 1065353216如何表示1.0f

Because 1065353216 is the unsigned 32-bit integer representation of the 32-bit floating point value 1.0. 因为1065353216是32位浮点值1.0的无符号32位整数表示。

More specifically, 1.0 as a 32-bit float becomes: 更具体地说,1.0作为32位浮点数变为:

0....... ........ ........ ........ sign bit (zero is positive)
.0111111 1....... ........ ........ exponent (127, which means zero)
........ .0000000 00000000 00000000 mantissa (zero, no correction needed)
___________________________________
00111111 10000000 00000000 00000000 result

So the end result is 2^0 + 0, which is 1 + 0, which is 1. 因此最终结果是2 ^ 0 + 0,即1 + 0,即1。

You can use binaryconvert.com or this useful converter to see other values. 您可以使用binaryconvert.com此有用的转换器来查看其他值。

As to why 127 suddenly means zero in the exponent: it's actually a pretty clever trick called exponent bias that makes it easier to compare floating-point values. 至于为什么127突然在指数中表示零:实际上这是一个非常聪明的技巧,称为指数偏差 ,它使比较浮点值变得更加容易。 Try out the converter with wildly different values (10, 100, 1000...) and you'll see the the exponent increases as well. 尝试使用截然不同的值(10、100、1000 ...)的转换器,您还会看到指数也增加。 Sorting is also the reason the sign bit is the first bit stored. 排序也是符号位是存储的第一位的原因。

The float is represented in binary32 format. floatbinary32格式表示。 The positive floats go from 0.0f (whose bits when interpreted as integer represent 0) to +inf (whose bits interpreted as integer represent approximately 2000000000). 正浮点数从0.0f (其位被解释为整数表示0时)到+inf (其位被解释为整数表示大约2000000000)。

The number 1.0f is almost exactly halfway between these two extremes. 数字1.0f几乎恰好介于这两个极端之间。 There are approximately as many positive float numbers below it (10 -1 , 10 -2 , …) as there are values above it (10 1 , 10 2 , …). 大约有如下它许多正的浮点数(10 -1,10 -2,...),因为有其以上的值(10 1,10 2,...)。 For this reason the value of 1.0f when its bits are interpreted as an integer is near 1000000000. 因此,将其位解释为整数时的1.0f值接近1000000000。

You can see the binary representation of the floating number 1.0 with the following lines of code: 您可以通过以下几行代码来看到浮点数1.0的二进制表示形式:

#include <stdio.h>
  int main(void) {
  float a = 1.0;
  printf("in hex, this is %08x\n", *((int*)(&a)));
  printf("the int representation is %d\n", *((int*)(&a)));
  return 0;
}

This results in 这导致

in hex, this is 3f800000
the int representation is 1065353216

The format of a 32 bit floating point number is given by 32位浮点数的格式为

1 sign bit      (s)    = 0
8 exponent bits (e)    = 7F = 127
23 mantissa bits (m)   = 0

You add a (implied) 1 in front of the mantissa - in the above case the mantissa is all zeros, and the implied value is 您在尾数前面添加一个(隐含的)1-在上面的例子中,尾数全为零,其隐含值为

1000 0000 0000 0000 0000 0000

This is 2^23 or 8388608. Now you multiply by (-1)^sign - which is 1 in this case. 这是2 ^ 23或8388608。现在您乘以(-1)^sign sign-在这种情况下为1

Finally, you multiply by 2^(exponent-150). 最后,乘以2 ^(exponent-150)。 Really, you should express the mantissa as a fraction (1.0000000) and multiply by 2^(exponent-127), but that's the same thing. 确实,您应该将尾数表示为分数(1.0000000)并乘以2 ^(exponent-127),但这是同一回事。 Either way, the result is 1.0 无论哪种方式,结果都是1.0

That should clear it up for you. 那应该为您清除它。

UPDATE it was pointed out in the comments that my code example may invoke undefined behavior, although my gcc compiler generated no warnings / errors. UPDATE在注释中指出,尽管我的gcc编译器未生成任何警告/错误,但我的代码示例可能会调用未定义的行为。 The below code is a more correct way to prove that 1.0 is 1065353216 in int (for 32 bit int and float ...): 下面的代码是一种更正确的方法,以证明1.0int 1065353216 (对于32位intfloat ...):

#include <stdio.h>

union {
  int i;
  float a;
} either;

int main(void) {
  either.a = 1.0;
  printf("in hex, this is %08x\n", either.i);
  printf("the int representation is %d\n", either.i);
  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM