2

采取以下代码:

const float fValue = 5.5f;
const float globalMin = 0.0f;
const float globalMax = 5.0f;
float vFactor = (float)(2e9 / (globalMax - globalMin));
int iValue = (int)((fValue - globalMin) * vFactor); 

最后一行导致一个溢出的值int。在 C# 中,结果未指定:

  • 6.2.1 显式数字转换
  • 对于从 float 或 double 到整数类型的转换,处理取决于发生转换的溢出检查上下文(第 7.6.12 节):
    • 在未经检查的上下文中,转换始终成功,并按如下方式进行。
      • 如果操作数的值为 NaN 或无穷大,则转换的结果是目标类型的未指定值。
      • 否则,源操作数向零舍入到最接近的整数值。如果这个整数值在目标类型的范围内,那么这个值就是转换的结果。
      • 否则,转换的结果是目标类型的未指定值。

在java中......好吧,我不知道,这就是我在这里的原因。我知道如何处理典型的整数溢出(即Integer.MAX_VALUE + 1),但我在规范中找不到任何将溢出作为从float.

在我的测试(Java)中,最后一行的结果告诉我,如果值简单地翻转Integer.MAX_VALUE,我会期望它会发生更多事情。-2094967296看起来JavaMAX_VALUE在溢出时被截断。

编辑:感谢@Pascal Cuoq 指出将浮点数截断为 int 的 SSE2 汇编指令会在溢出时产生 INT_MIN。我将修复 C# 端的错误,但我仍然对 Java 在哪里/是否指定此行为感到好奇。

4

1 回答 1

2

数据类型之间的转换在 Java 语言规范中有很好的定义(参见Conversions and Promotions部分)。

我相信你的案子属于5.1.3。缩小原始转换,您可以看到:

  • 首先,您的浮点数将使用 IEEE 754 向零舍入模式舍入为整数(在此处解释)和
  • 它将被分配最大或最小的可表示整数值,具体取决于该值是太小还是太大。
于 2013-08-22T21:28:46.717 回答