代码之家  ›  专栏  ›  技术社区  ›  Homam

为什么[float.MaxValue==float.MaxValue+1]返回true?

  •  28
  • Homam  · 技术社区  · 14 年前

    我想知道你能否解释浮点类型中的溢出。

    float.MaxValue == float.MaxValue + 1 // returns true
    
    5 回复  |  直到 13 年前
        1
  •  24
  •   Guffa    14 年前

    因为 1 太小了不能在 float.MaxValue 价值。

    任何小于1e32的都将低于浮点的精度,所以实际上等于加一个零。

    编辑:

    ulrichb表明,值1e23实际上会影响float.MaxValue,这意味着您根本没有比较float,而是比较double。编译器在添加和比较之前将所有值转换为双精度值。

        2
  •  9
  •   ulrichb    14 年前

    很有意思:

    float fMax = float.MaxValue;
    double dMax = double.MaxValue;
    
    Console.WriteLine("{0}, {1}", fMax == fMax + 1E22f, fMax + 1E22f);
    Console.WriteLine("{0}, {1}", fMax == fMax + 1E23f, fMax + 1E23f);
    
    Console.WriteLine("{0}, {1}", dMax == dMax + 1E291d, dMax + 1E291d);
    Console.WriteLine("{0}, {1}", dMax == dMax + 1E292d, dMax + 1E292d);
    

    印刷品:

    True, 3.402823E+38
    False, 3.402823E+38
    True, 1.79769313486232E+308
    False, Infinity
    

    所以。。。正如古法所说 fMax + 1E23f 转换为双精度 dMax + 1E292d 加起来 Infinity .

        3
  •  3
  •   Dirk Vollmar    14 年前

    这里的问题是浮点精度。 float.MaxValue 对应于3.40228E+038f。但是 float 精度要低得多,实际上,只有7位数的精度。

    任何超过这个精度的东西都是“用零填充”的,在这个高数字上加1不会改变它。

        4
  •  3
  •   Ben Voigt    14 年前

    简而言之,差别在第39位,并且 float 只存储前7个(ish)。这是浮点运算的一个特点。

        5
  •  0
  •   spalmer    10 年前

    要使float类型的临时变量实际保存单个精度值,必须从内存中的float变量加载该变量。编译器通常被允许以比所需精度更高的精度来表示单精度值,并且在值位于寄存器中时倾向于这样做。当它溢出回内存时,额外的精度就会丢失。