如果您将一个大整数转换为浮点数会发生什么

markus_p

这是一个关于使用gcc 4.4将非常大/小的SIGNED整数强制转换为浮点数时究竟发生了什么的一般问题。

进行投射时,我看到一些奇怪的行为。这里有些例子:

必须通过以下方法获得:

float f = (float)x;
unsigned int r;
memcpy(&r, &f, sizeof(unsigned int));

./btest -f float_i2f -1 0x80800001
input:          10000000100000000000000000000001
absolute value: 01111111011111111111111111111111

exponent:       10011101
mantissa:       00000000011111101111111111111111  (right shifted absolute value)

EXPECT:         11001110111111101111111111111111  (sign|exponent|mantissa)
MUST BE:        11001110111111110000000000000000  (sign ok, exponent ok,
                                                     mantissa???)

./btest -f float_i2f -1 0x3f7fffe0

EXPECT:    01001110011111011111111111111111
MUST BE:   01001110011111100000000000000000

./btest -f float_i2f -1 0x80004999                                                                  


EXPECT:    11001110111111111111111101101100
MUST BE:   11001110111111111111111101101101    (<- 1 added at the end)

因此,令我困扰的是,在两个示例中,尾数都是不同的,然后我只是将整数值向右移动。例如,末尾的零。他们来自哪里?

我只在大/小值上看到此行为。范围为-2 ^ 24、2 ^ 24的值可以正常工作。

我想知道是否有人可以启发我这里发生的事情。采取什么步骤来实现非常大/小的价值。

这是对:函数的一个附加问题:函数将float转换为int(巨大的整数),这不像这里的一般。

编辑代码:

unsigned float_i2f(int x) {
  if (x == 0) return 0;
  /* get sign of x */
  int sign = (x>>31) & 0x1;

  /* absolute value of x */
  int a = sign ? ~x + 1 : x;

  /* calculate exponent */
  int e = 158;
  int t = a;
  while (!(t >> 31) & 0x1) {
    t <<= 1;
    e--;
  };

  /* calculate mantissa */
  int m = (t >> 8) & ~(((0x1 << 31) >> 8 << 1));
  m &= 0x7fffff;

  int res = sign << 31;
  res |= (e << 23);
  res |= m;

  return res;
}

编辑2:

在亚当斯(Adams)评论和引用《写伟大的代码》一书之后,我用四舍五入更新了我的例程。我仍然遇到一些舍入错误(幸运的是现在只有1位错误)。

现在,如果我进行测试运行,我将获得大部分良好的结果,但会出现一些四舍五入的错误,如下所示:

input:  0xfefffff5
result: 11001011100000000000000000000101
GOAL:   11001011100000000000000000000110  (1 too low)

input:  0x7fffff
result: 01001010111111111111111111111111
GOAL:   01001010111111111111111111111110  (1 too high)

unsigned float_i2f(int x) {
  if (x == 0) return 0;
  /* get sign of x */
  int sign = (x>>31) & 0x1;

  /* absolute value of x */
  int a = sign ? ~x + 1 : x;

  /* calculate exponent */
  int e = 158;
  int t = a;
  while (!(t >> 31) & 0x1) {
    t <<= 1;
    e--;
  };

  /* mask to check which bits get shifted out when rounding */
  static unsigned masks[24] = {
    0, 1, 3, 7, 
    0xf, 0x1f, 
    0x3f, 0x7f, 
    0xff, 0x1ff, 
    0x3ff, 0x7ff, 
    0xfff, 0x1fff, 
    0x3fff, 0x7fff, 
    0xffff, 0x1ffff, 
    0x3ffff, 0x7ffff, 
    0xfffff, 0x1fffff, 
    0x3fffff, 0x7fffff
  };

  /* mask to check wether round up, or down */
  static unsigned HOmasks[24] = {
    0,
    1, 2, 4, 0x8, 0x10, 0x20, 0x40, 0x80,
    0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000
  };

  int S = a & masks[8];
  int m = (t >> 8) & ~(((0x1 << 31) >> 8 << 1));
  m &= 0x7fffff;

  if (S > HOmasks[8]) {
    /* round up */
    m += 1;
  } else if (S == HOmasks[8]) {
    /* round down */
    m = m + (m & 1);
  }

  /* special case where last bit of exponent is also set in mantissa
   * and mantissa itself is 0 */
  if (m & (0x1 << 23)) {
    e += 1;
    m = 0;
  }

  int res = sign << 31;
  res |= (e << 23);
  res |= m;
  return res;
}

有人知道问题出在哪里吗?

亚当·科西里克(Adam Kosiorek)

C / C ++浮点数倾向于与IEEE 754浮点标准(例如,在gcc中)兼容。零来自舍入规则

将数字向右移动会使右侧的一些位消失。我们称他们为guard bits现在,我们将其称为数字HO的最高位和LO最低位。现在假设guard bits仍然是我们数字的一部分。例如,如果我们有3,guard bits则意味着我们的LO位的值为8(如果已设置)。现在,如果:

  1. guard bits> 0.5 *值LO

    将数字四舍五入为可能的较小较大值,而忽略符号

  2. '保护位'的值== 0.5 *的值 LO

    • 如果LO== 0,则使用当前数字值
    • 数字+ = 1否则
  3. guard bits<0.5 *值LO

    • 使用当前数字值

为什么3个保护位表示LO值为8?

假设我们有一个二进制的8位数字:

weights:    128 64 32 16 8 4 2 1
binary num:   0  0  0  0 1 1 1 1

让我们将其右移3位:

weights:      x x x 128 64 32 16 8 | 4 2 1
binary num:   0 0 0   0  0  0  0 1 | 1 1 1

如您所见,具有3个保护位,该LO位结束于第4个位置,权重为8。这仅适用于舍入目的。之后必须对权重进行“归一化”,以便LO的权重再次变为1。

以及如果保护位> 0.5 * value,我该如何用位操作进行检查?

最快的方法是使用查找表。假设我们正在处理一个8位数字:

unsigned number;          //our number
unsigned bitsToShift;     //number of bits to shift

assert(bitsToShift < 8);  //8 bits

unsigned guardMasks[8] = {0, 1, 3, 7, 0xf, 0x1f, 0x3f}
unsigned LOvalues[8] = {0, 1, 2, 4, 0x8, 0x10, 0x20, 0x40} //divided by 2 for faster comparison

unsigned guardBits = number & guardMasks[bitsToShift]; //value of the guard bits
number = number >> bitsToShift;

if(guardBits > LOvalues[bitsToShift]) {
...
} else if (guardBits == LOvalues[bitsToShift]) {
...
} else { //guardBits < LOvalues[bitsToShift]
...
}

参考:兰德尔·海德(Randall Hyde)撰写伟大的代码,第1卷

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Pygame-如果您将一个矩形的矩形比一个矩形小的表面会发生什么?

来自分类Dev

它是否定义了如果您浮动一个浮点会发生什么?

来自分类Dev

将浮点数转换为下一个整数,而不是最接近的整数?

来自分类Dev

Elixir一个将浮点数和整数都转换为位串的函数?

来自分类Dev

将多于一个点的字符串转换为浮点数或整数?

来自分类Dev

将浮点数转换为整数

来自分类Dev

将整数转换为浮点数

来自分类Dev

为什么这个整数被认为是一个浮点数?

来自分类Dev

如果您递归地返回一个函数会发生什么,这是一种好习惯吗?

来自分类Dev

如何将字符串转换为浮点数(如果它是一个确切的数字),而不仅以javascript中的数字开头

来自分类Dev

如果您指定一个value_types不同的分配器,会发生什么?

来自分类Dev

优化:将浮点数乘以整数或另一个浮点数是否更快

来自分类Dev

我如何在 Python 中定义一个函数来将对象列转换为浮点数?

来自分类Dev

如何制作一个检测字符串中的因子并将其转换为浮点数的函数?

来自分类Dev

为什么我们将整数除法分别转换为“浮点数”?

来自分类Dev

为什么Pandas数据框将整数转换为浮点数据类型

来自分类Dev

浮点数转换为int以获得大价值

来自分类Dev

PHP-强制整数转换为带有三个小数的浮点数

来自分类Dev

浮点数转换为整数时如何舍入

来自分类Dev

将Google Location LatLong整数转换为浮点数

来自分类Dev

将“无限”浮点数转换为整数

来自分类Dev

将浮点数转换为双精度整数

来自分类Dev

如何将浮点数转换为整数?

来自分类Dev

浮点数转换为C中的24位整数

来自分类Dev

将整数列表转换为浮点数

来自分类Dev

python数据帧将整数转换为浮点数

来自分类Dev

无法将浮点数转换为整数

来自分类Dev

如何将整数转换为浮点数?

来自分类Dev

当我将null转换为另一个类时会发生什么

Related 相关文章

  1. 1

    Pygame-如果您将一个矩形的矩形比一个矩形小的表面会发生什么?

  2. 2

    它是否定义了如果您浮动一个浮点会发生什么?

  3. 3

    将浮点数转换为下一个整数,而不是最接近的整数?

  4. 4

    Elixir一个将浮点数和整数都转换为位串的函数?

  5. 5

    将多于一个点的字符串转换为浮点数或整数?

  6. 6

    将浮点数转换为整数

  7. 7

    将整数转换为浮点数

  8. 8

    为什么这个整数被认为是一个浮点数?

  9. 9

    如果您递归地返回一个函数会发生什么,这是一种好习惯吗?

  10. 10

    如何将字符串转换为浮点数(如果它是一个确切的数字),而不仅以javascript中的数字开头

  11. 11

    如果您指定一个value_types不同的分配器,会发生什么?

  12. 12

    优化:将浮点数乘以整数或另一个浮点数是否更快

  13. 13

    我如何在 Python 中定义一个函数来将对象列转换为浮点数?

  14. 14

    如何制作一个检测字符串中的因子并将其转换为浮点数的函数?

  15. 15

    为什么我们将整数除法分别转换为“浮点数”?

  16. 16

    为什么Pandas数据框将整数转换为浮点数据类型

  17. 17

    浮点数转换为int以获得大价值

  18. 18

    PHP-强制整数转换为带有三个小数的浮点数

  19. 19

    浮点数转换为整数时如何舍入

  20. 20

    将Google Location LatLong整数转换为浮点数

  21. 21

    将“无限”浮点数转换为整数

  22. 22

    将浮点数转换为双精度整数

  23. 23

    如何将浮点数转换为整数?

  24. 24

    浮点数转换为C中的24位整数

  25. 25

    将整数列表转换为浮点数

  26. 26

    python数据帧将整数转换为浮点数

  27. 27

    无法将浮点数转换为整数

  28. 28

    如何将整数转换为浮点数?

  29. 29

    当我将null转换为另一个类时会发生什么

热门标签

归档