PP_10大于或等于 'int.最大值'



我正在尝试编写一个转换函数,该函数采用float并返回int,这基本上是进行饱和转换。如果 it 大于int.MaxValue则应返回int.MaxValue,同样用于int.MinValue

我宁愿不捕获异常作为正常流量控制的一部分,而只是显式检查边界,除非我不确定上限是多少,因为可以存储在 int 中的最大浮点小于int.MaxValue因为浮点数的精度低于该大小的值的 int。

基本上我正在寻找以下...

float largestFloatThatCanBeStoredInAnInt = ...

让我们做一个实验

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

因此,我们可以得出结论,可以转换为int的最大float2147483520。可以投射到float并返回int的最大int2147483583; 如果我们尝试投射2147483583 + 1 = 2147483584我们会得到2147483650f如果我们尝试将其投射回int,这将抛出 excpetion .

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

最后,floatint转换(无例外;int.MaxValueint.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;

我建议你把它硬编码为正确的数据类型:

var largestFloatThatCanBeStoredInAnInt = 2147483000f;

2,147,483,000 是您可以存储在小于int.MaxValue的浮点数中的最大值

此方法可解决此问题:

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结果会使此函数返回错误的值。

这行不通吗?

float largestFloatThatCanBeStoredInAnInt = (float)int.MaxValue - 1;

此表达式为真:

(float)int.MaxValue - 1 < int.MaxValue

最新更新