采取以下代码:
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 在哪里/是否指定此行为感到好奇。