我正在尝试编写一个转换函数,该函数需要一个float
并返回一个int
,基本上可以完成饱和转换。如果它大于int.MaxValue
,则应返回int.MaxValue
,对于int.MinValue
同样。
我不希望在常规流控制中捕获异常,而只是显式地检查边界,除非我不确定上限是多少,因为可以存储在int中的最大浮点数小于{对于大小相同的值,{1}}的浮点精度要小于int精度。
基本上,我在以下位置寻找int.MaxValue
:
...
答案 0 :(得分:2)
我建议您将其硬编码为正确的数据类型:
var largestFloatThatCanBeStoredInAnInt = 2147483000f;
2,147,483,000是您可以存储在小于int.MaxValue
的浮点数中的最高值
答案 1 :(得分:2)
让我们进行一次实验:
float best = 0f;
for (int i = 2147483000; ; ++i)
{
float f = (float)i;
try
{
checked
{
int v = (int)f;
}
best = f;
}
catch (OverflowException)
{
string report = string.Join(Environment.NewLine,
$" max float = {best:g10}",
$"min overflow = {f:g10}",
$" max int = {i - 1}");
Console.Write(report);
break;
}
}
结果是
max float = 2147483520
min overflow = 2147483650
max int = 2147483583
因此我们可以得出结论,可以强制转换为float
的最大int
是2147483520
。可以转换为int
并返回到float
的最大int
是2147483583
;
如果我们尝试投射2147483583 + 1 = 2147483584
,我们将得到2147483650f
,如果我们尝试将其投射回int
,则会抛出异常。
int overflow = 2147483583 + 1;
int back = checked((int)(float) overflow); // <- throws exception
甚至
float f_1 = 2147483583f; // f_1 == 2147483520f (rounding)
int i_1 = checked((int) f_1); // OK
float f_2 = 2147483584f; // f_2 == 2147483650f (rounding) > int.MaxValue
int i_2 = checked((int) f_2); // throws exception
最后,从float
到int
的转换(无例外; int.MaxValue
或int.MinValue
,如果float
不在范围内) :
// float: round errors (mantissa has 23 bits only: 23 < 32)
public static int ClampToInt(this float x) =>
x > 2147483520f ? int.MaxValue
: x < -2147483650f ? int.MinValue
: (int) x;
// double: no round errors (mantissa has 52 bits: 52 > 32)
public static int ClampToInt(this double x) =>
x > int.MaxValue ? int.MaxValue
: x < int.MinValue ? int.MinValue
: (int) x;
答案 2 :(得分:1)
此方法可解决以下问题:
public static int ClampToInt(this float x)
{
const float maxFloat = int.MaxValue;
const float minFloat = int.MinValue;
return x >= maxFloat ? int.MaxValue : x <= minFloat ? int.MinValue : (int) x;
}
在这里使用>=
很重要。仅使用>
,您会错过(float) int.MaxValue
,然后在进行普通转换时,您会发现(int) (float) int.MaxValue == int.MinValue
,其结果将使该函数返回错误的值。>
答案 3 :(得分:-1)
那行不通吗?
float largestFloatThatCanBeStoredInAnInt = (float)int.MaxValue - 1;
此表达式正确:
(float)int.MaxValue - 1 < int.MaxValue
答案 4 :(得分:-1)
为什么不检查限额?
if(myFloat > int.MaxValue)
return int.MaxValue;
if(myFloat < int.MinValue)
return int.MinValue;