小于或等于“ int.MaxValue”的最大“浮点数”

时间:2019-07-03 08:17:42

标签: c# .net floating-point int rounding

我正在尝试编写一个转换函数,该函数需要一个float并返回一个int,基本上可以完成饱和转换。如果它大于int.MaxValue,则应返回int.MaxValue,对于int.MinValue同样。

我不希望在常规流控制中捕获异常,而只是显式地检查边界,除非我不确定上限是多少,因为可以存储在int中的最大浮点数小于{对于大小相同的值,{1}}的浮点精度要小于int精度。

基本上,我在以下位置寻找int.MaxValue

...

5 个答案:

答案 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的最大int2147483520。可以转换为int并返回到float的最大int2147483583; 如果我们尝试投射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

最后,从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;

答案 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;