当值溢出时,将浮点类型转换为无符号整数类型会发生什么? [英] What happens when casting floating point types to unsigned integer types when the value would overflow?

查看:202
本文介绍了当值溢出时,将浮点类型转换为无符号整数类型会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道当C中从浮点类型转换为无符号整数类型时,如果所讨论的整数类型无法准确表示该值,会发生什么情况.举个例子

I'm wondering what happens when casting from a floating point type to an unsigned integer type in C when the value can't be accurately represented by the integer type in question. Take for instance

func (void)
{
float a = 1E10;
unsigned b = a;
}

我在系统上得到的b的值(系统上的unsigned能够表示从0到2 32 -1的值)是1410065408.在我看来,这很明智,因为它只是转换结果的最低位.

The value of b I get on my system (with unsigned on my system being able to represent values from 0 to 232-1) is 1410065408. This seems sensible to me because it's simply the lowest order bits of the result of the cast.

我相信此类操作的行为未由标准定义.我错了吗?如果我做这样的事情,我会在实践中期望什么?

I believe the behavior of operations such as these is undefined by the standard. Am I wrong? What can I expect in practice if I do things like this?

还有,带符号类型会怎样?如果b的类型为int,我得到的是-2147483648,这对我来说真的没有意义.

Also, what happens with signed types? If b is of type int, I get -2147483648, which doesn't really make sense to me.

推荐答案

当值溢出时,将浮点类型转换为无符号整数类型会发生什么?

What happens when casting floating point types to unsigned integer types when the value would overflow (?)

未定义的行为(UB)

另外 @ user694733 很好的答案,以防止由于超出范围而导致的未定义行为floatunsigned的代码可以首先测试float的值.

In addition @user694733 fine answer, to prevent undefined behavior caused by out of range float to unsigned code can first test the float value.

对于无符号类型,尤其是有符号类型,对该范围的测试非常棘手.详细信息是整数转换之前的所有转换和常量都必须精确.接近极限的FP数学也必须准确.

Yet testing for the range is tricky, for unsigned types and especially for signed types. The detail is that all conversions and constants prior to the integer conversion must be exact. FP math near the limits needs to be exact too.

示例:

转换为32位无符号的范围为-0.999 ...至4294967295.999....

Conversion to a 32-bit unsigned is valid for the range -0.999... to 4294967295.999....

转换为32位2的补码符号在-2147483648.999 ...到2147483647.999 ...范围内有效.

Conversion to a 32-bit 2's complement signed is valid for the range -2147483648.999... to 2147483647.999....

// code uses FP constants that are exact powers-of-2 to insure their exact encoding.

// Form a FP constant that is exactly UINT_MAX + 1
#define FLT_UINT_MAX_P1 ((UINT_MAX/2 + 1)*2.0f)

bool convert_float_to_unsigned(unsigned *u, float f) {
  if (f > -1.0f && f < FLT_UINT_MAX_P1) {
    *u = (unsigned) f;
    return true;
  }
  return false;  // out of range
}


#define FLT_INT_MAX_P1 ((INT_MAX/2 + 1)*2.0f)
bool convert_float_to_int(int *i, float f) {
  #if INT_MIN == -INT_MAX
  // Rare non 2's complement integer
  if (fabsf(f) < FLT_INT_MAX_P1) {
    *i = (int) f;
    return true;
  }
  #else
  // Do not use f + 1 > INT_MIN as it may incur rounding
  // Do not use f > INT_MIN - 1.0f as it may incur rounding
  // f - INT_MIN is expected to be exact for values near the limit
  if (f - INT_MIN > -1 && f < FLT_INT_MAX_P1) {
    *i = (int) f;
    return true;
  }
  #endif 
  return false;  // out of range
}


pedantic代码将采取其他步骤来应对罕见的FLT_RADIX 10.

FLT_EVAL_METHOD可能会起作用,但可以使float数学的计算精度更高,但是到目前为止,我还没有看到它对上述解决方案产生负面影响.

FLT_EVAL_METHOD, which allows for float math be calculated at higher precision, may play a role, yet so far I do not see it negatively affecting the above solution.

这篇关于当值溢出时,将浮点类型转换为无符号整数类型会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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