【问题标题】:C# - Int operation inexplicably returning negative valueC# - Int 操作莫名其妙地返回负值
【发布时间】:2013-08-02 16:20:40
【问题描述】:

操作如下:

public float InfectionPercent()
{
    return (infected + zombies) * 100 / population;
}

值是:

int infected = 20196093
int zombies = 1978138
int population = 32608521

返回值为-63

100 更改为 100f 可以解决此问题。


为什么该操作返回-63 而不是63

【问题讨论】:

  • 什么是感染者、僵尸、人口类型?短的?诠释?
  • @LoganMurphy 操作忘记了!他们都是ints
  • 可能 .Net 足够聪明,可以理解周围没有僵尸

标签: c# floating-point int


【解决方案1】:
20196093 + 1978138 = 22174231
22174231 * 100 = 2 217 423 100

但是,Int.MaxValue 是 2 147 483 647,所以你正在破坏最大值。

通过将100 设置为float,您将强制进行浮点乘法。有效的 float 值介于 -3.4 × 10^38+3.4 × 10^38 之间(即 340 undecillion,即相当多),因此它确实是正确的。

【讨论】:

  • 浮点数不受相同最大值的约束?或者花车还有其他事情发生?
  • 为什么不将它们都设置为长?
  • @RadiantHex Float 范围从 -3.4 × 10^38+3.4 × 10^38 所以不,这完全不是同一个最大值。
  • @EricPostpischil float 有常量infinity,但不能包含无限数,它停在3.4 x 10^38。如果您需要存储更大的数字,则可以使用两倍于 1.7 × 10^308。我的意思是,例如,一台计算机不可能在寄存器中包含数字 1 后跟 1000 亿个其他 1,这太愚蠢了。它不可能是无限的,因为存储空间是有限的。
  • @ChrisSinclair: float.MaxValue +1 计算结果为 float.MaxValue 因为四舍五入。试试float.MaxValue*float.MaxValue
【解决方案2】:

这是一个整数溢出错误

2,147,483,647 是最大的 c# 整数值

20,196,093 + 1,978,138 = 22,174,231

22,174,231 * 100 = 22,174,231 * 100 = 2,217,423,100

(整数溢出到-2,077,544,195

-2,077,544,195 / 32,608,521 = -63.71169655318007

转换为浮点数可以防止这个问题,因为浮点数不会在很长一段时间内溢出,而当它溢出时,它最终会是无限的。

【讨论】:

    【解决方案3】:

    解决该问题的方法是像使用 100f 那样强制进行浮点乘法(原因由 Pierre-Luc Pineault 解释)。但是,如果您希望在不显式转换的情况下返回整数结果,请将变量设为 uint,因为它们只能为正数。

    uint infected = 20196093
    uint zombies = 1978138
    uint population = 32608521
    
    public uint InfectionPercent()
    {
        return (infected + zombies) * 100 / population;
    }
    
    //output is 68 (float output is 68.00134)
    

    可能不是瓶颈,但如果是实时游戏,您可能会获得更好的性能,因为您避免将int 转换为float(当然,这可能是一个微优化,具体取决于你多久调用一次)。

    编辑 - 正如 Chris 在 cmets 中正确提到的那样,在这种情况下最好使用 long 而不是 uint

    【讨论】:

    • 我建议使用long(或ulong)而不是uintuint 只会使溢出命中的上限翻倍,这仍然很合理。
    • @ChrisSinclair - +1 这是一个很好的观点。好久没用long了,没想到。
    【解决方案4】:

    整数可以容纳的最大数是 2,147,483,647。如果你的变量受感染和僵尸都是整数,它们会超过这个数字,因为 {(infected + zombies) * 100} = 2,217,423,100 > 2,147,483,647。因为它最大化了整数,所以变成了负数。尝试将受感染和僵尸变量变为浮点数或通过将 100 变为 100.00 来强制浮点乘法。

    【讨论】:

    • int 的最大值可能是 2,147,483,647,但肯定有更大的整数。 “整数”不代表int
    猜你喜欢
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    相关资源
    最近更新 更多