Skip to content

Latest commit

 

History

History
207 lines (190 loc) · 7.56 KB

int转换float再转换回int.md

File metadata and controls

207 lines (190 loc) · 7.56 KB

int转换float再转换回int

最近在看深入理解计算机系统,看到第2章的习题其中有一个将int型数字转换为float再转换为int是否会改变数字大小?自己刚开始一直觉得float能表示的数字范围是3.402823e+38大于int的最大值,所以我认为这样转换不会改变数字大小。结果试了一个例子立马就打脸了:

  int num = (int)(pow(2, 24) + 1);  /* 1000001 length > 6 so trim last 1 */
  printf("%x\n", num);
  printf("%d\n", num);
  printf("%f\n", (float)num);
  printf("%d\n", (int)(float)num);
  printf("%x\n", (int)(float)num);
  printf("%x\n", (int)(double)num);

运行结果如下:

1000001
16777217
16777216.000000
16777216
1000000
1000001

由此可以看出(int)(float)num的取值是16777216,比实际的值正好小于1。

在找了两天的后,忽然在stackoverflow上找到一个解答,简单翻译如下一下。参考链接

C语言中float是IEEE-754单精度32位浮点数编码,int同样也是32位。相比较于int的32位,float的小数段仅仅有24位精度表示。因此int的值从0到16777215可以在float精确的表示,比16777215大的数字不一定能用float精确表示。可以用下面的代码测试:

for (int a = 16777210; a < 16777224; a++)
{
  float b = a;
  int c = b;
  printf("a=%d c=%d b=0x%08x\n", a, c, *((int *)&b));
}

运行结果如下:

a=16777210 c=16777210 b=0x4b7ffffa
a=16777211 c=16777211 b=0x4b7ffffb
a=16777212 c=16777212 b=0x4b7ffffc
a=16777213 c=16777213 b=0x4b7ffffd
a=16777214 c=16777214 b=0x4b7ffffe
a=16777215 c=16777215 b=0x4b7fffff
a=16777216 c=16777216 b=0x4b800000
a=16777217 c=16777216 b=0x4b800000
a=16777218 c=16777218 b=0x4b800001
a=16777219 c=16777220 b=0x4b800002
a=16777220 c=16777220 b=0x4b800002
a=16777221 c=16777220 b=0x4b800002
a=16777222 c=16777222 b=0x4b800003
a=16777223 c=16777224 b=0x4b800004

可以看出,float值0x4b800002代表了3个int值,16777219, 16777220, 16777221,因此将16777219转换到float再转换回int不会保存真实的int的值。

接近于INT_MAX的浮点数是0x4effffff和0x4f000000两个,可以这段代码来描述:

for (int a = 2147483520; a < 2147483647; a++)
{
  float b = a;
  int c = b;
  printf("a=%d c=%d b=0x%08x\n", a, c, *((int *)&b));
}

运行结果如下:

a=2147483520 c=2147483520 b=0x4effffff
a=2147483521 c=2147483520 b=0x4effffff
a=2147483522 c=2147483520 b=0x4effffff
a=2147483523 c=2147483520 b=0x4effffff
a=2147483524 c=2147483520 b=0x4effffff
a=2147483525 c=2147483520 b=0x4effffff
a=2147483526 c=2147483520 b=0x4effffff
a=2147483527 c=2147483520 b=0x4effffff
a=2147483528 c=2147483520 b=0x4effffff
a=2147483529 c=2147483520 b=0x4effffff
a=2147483530 c=2147483520 b=0x4effffff
a=2147483531 c=2147483520 b=0x4effffff
a=2147483532 c=2147483520 b=0x4effffff
a=2147483533 c=2147483520 b=0x4effffff
a=2147483534 c=2147483520 b=0x4effffff
a=2147483535 c=2147483520 b=0x4effffff
a=2147483536 c=2147483520 b=0x4effffff
a=2147483537 c=2147483520 b=0x4effffff
a=2147483538 c=2147483520 b=0x4effffff
a=2147483539 c=2147483520 b=0x4effffff
a=2147483540 c=2147483520 b=0x4effffff
a=2147483541 c=2147483520 b=0x4effffff
a=2147483542 c=2147483520 b=0x4effffff
a=2147483543 c=2147483520 b=0x4effffff
a=2147483544 c=2147483520 b=0x4effffff
a=2147483545 c=2147483520 b=0x4effffff
a=2147483546 c=2147483520 b=0x4effffff
a=2147483547 c=2147483520 b=0x4effffff
a=2147483548 c=2147483520 b=0x4effffff
a=2147483549 c=2147483520 b=0x4effffff
a=2147483550 c=2147483520 b=0x4effffff
a=2147483551 c=2147483520 b=0x4effffff
a=2147483552 c=2147483520 b=0x4effffff
a=2147483553 c=2147483520 b=0x4effffff
a=2147483554 c=2147483520 b=0x4effffff
a=2147483555 c=2147483520 b=0x4effffff
a=2147483556 c=2147483520 b=0x4effffff
a=2147483557 c=2147483520 b=0x4effffff
a=2147483558 c=2147483520 b=0x4effffff
a=2147483559 c=2147483520 b=0x4effffff
a=2147483560 c=2147483520 b=0x4effffff
a=2147483561 c=2147483520 b=0x4effffff
a=2147483562 c=2147483520 b=0x4effffff
a=2147483563 c=2147483520 b=0x4effffff
a=2147483564 c=2147483520 b=0x4effffff
a=2147483565 c=2147483520 b=0x4effffff
a=2147483566 c=2147483520 b=0x4effffff
a=2147483567 c=2147483520 b=0x4effffff
a=2147483568 c=2147483520 b=0x4effffff
a=2147483569 c=2147483520 b=0x4effffff
a=2147483570 c=2147483520 b=0x4effffff
a=2147483571 c=2147483520 b=0x4effffff
a=2147483572 c=2147483520 b=0x4effffff
a=2147483573 c=2147483520 b=0x4effffff
a=2147483574 c=2147483520 b=0x4effffff
a=2147483575 c=2147483520 b=0x4effffff
a=2147483576 c=2147483520 b=0x4effffff
a=2147483577 c=2147483520 b=0x4effffff
a=2147483578 c=2147483520 b=0x4effffff
a=2147483579 c=2147483520 b=0x4effffff
a=2147483580 c=2147483520 b=0x4effffff
a=2147483581 c=2147483520 b=0x4effffff
a=2147483582 c=2147483520 b=0x4effffff
a=2147483583 c=2147483520 b=0x4effffff
a=2147483584 c=-2147483648 b=0x4f000000
a=2147483585 c=-2147483648 b=0x4f000000
a=2147483586 c=-2147483648 b=0x4f000000
a=2147483587 c=-2147483648 b=0x4f000000
a=2147483588 c=-2147483648 b=0x4f000000
a=2147483589 c=-2147483648 b=0x4f000000
a=2147483590 c=-2147483648 b=0x4f000000
a=2147483591 c=-2147483648 b=0x4f000000
a=2147483592 c=-2147483648 b=0x4f000000
a=2147483593 c=-2147483648 b=0x4f000000
a=2147483594 c=-2147483648 b=0x4f000000
a=2147483595 c=-2147483648 b=0x4f000000
a=2147483596 c=-2147483648 b=0x4f000000
a=2147483597 c=-2147483648 b=0x4f000000
a=2147483598 c=-2147483648 b=0x4f000000
a=2147483599 c=-2147483648 b=0x4f000000
a=2147483600 c=-2147483648 b=0x4f000000
a=2147483601 c=-2147483648 b=0x4f000000
a=2147483602 c=-2147483648 b=0x4f000000
a=2147483603 c=-2147483648 b=0x4f000000
a=2147483604 c=-2147483648 b=0x4f000000
a=2147483605 c=-2147483648 b=0x4f000000
a=2147483606 c=-2147483648 b=0x4f000000
a=2147483607 c=-2147483648 b=0x4f000000
a=2147483608 c=-2147483648 b=0x4f000000
a=2147483609 c=-2147483648 b=0x4f000000
a=2147483610 c=-2147483648 b=0x4f000000
a=2147483611 c=-2147483648 b=0x4f000000
a=2147483612 c=-2147483648 b=0x4f000000
a=2147483613 c=-2147483648 b=0x4f000000
a=2147483614 c=-2147483648 b=0x4f000000
a=2147483615 c=-2147483648 b=0x4f000000
a=2147483616 c=-2147483648 b=0x4f000000
a=2147483617 c=-2147483648 b=0x4f000000
a=2147483618 c=-2147483648 b=0x4f000000
a=2147483619 c=-2147483648 b=0x4f000000
a=2147483620 c=-2147483648 b=0x4f000000
a=2147483621 c=-2147483648 b=0x4f000000
a=2147483622 c=-2147483648 b=0x4f000000
a=2147483623 c=-2147483648 b=0x4f000000
a=2147483624 c=-2147483648 b=0x4f000000
a=2147483625 c=-2147483648 b=0x4f000000
a=2147483626 c=-2147483648 b=0x4f000000
a=2147483627 c=-2147483648 b=0x4f000000
a=2147483628 c=-2147483648 b=0x4f000000
a=2147483629 c=-2147483648 b=0x4f000000
a=2147483630 c=-2147483648 b=0x4f000000
a=2147483631 c=-2147483648 b=0x4f000000
a=2147483632 c=-2147483648 b=0x4f000000
a=2147483633 c=-2147483648 b=0x4f000000
a=2147483634 c=-2147483648 b=0x4f000000
a=2147483635 c=-2147483648 b=0x4f000000
a=2147483636 c=-2147483648 b=0x4f000000
a=2147483637 c=-2147483648 b=0x4f000000
a=2147483638 c=-2147483648 b=0x4f000000
a=2147483639 c=-2147483648 b=0x4f000000
a=2147483640 c=-2147483648 b=0x4f000000
a=2147483641 c=-2147483648 b=0x4f000000
a=2147483642 c=-2147483648 b=0x4f000000
a=2147483643 c=-2147483648 b=0x4f000000
a=2147483644 c=-2147483648 b=0x4f000000
a=2147483645 c=-2147483648 b=0x4f000000
a=2147483646 c=-2147483648 b=0x4f000000

注意从2147483584到2147483647都被四舍五入到2147483648的浮点数。最大的int值被往下舍入到0x4effffff,在32位机器上同(INT_MAX - 64)。

因此,只有int在pow(2,24)以下,从int转换到float再转换回int可以精确匹配。