【问题标题】:Why does Math.Floor(Double) return a value of type Double?为什么 Math.Floor(Double) 返回 Double 类型的值?
【发布时间】:2009-08-28 19:28:31
【问题描述】:

我需要从十进制或双精度中获取左侧整数值。例如:我需要从 4.6 中得到值 4。我尝试使用 Math.Floor 函数,但它返回一个双精度值,例如:它从 4.6 返回 4.0。 MSDN 文档说它返回一个整数值。我在这里错过了什么吗?还是有其他方法可以实现我的目标?

【问题讨论】:

  • MSDN 文档说它返回一个整数值MSDN documentation 声明 Math.Floor 返回 System.Double,而不是整数。
  • 一个整数 value 是有效的,但这并不意味着它可以存储在“int”或“long”中。 “double”成功地存储了比“int”更宽的范围内的所有整数值注意,当尾数部分没有足够的位来存储整数值的所有数字时,一些整数值可能会被舍入,当它的基数为 2 指数时大于 52:对于大于 2^52 或小于 -2^52 的整数,可能会在“double”中舍入整数值,但结果仍将是可表示的最接近的整数;如果您使用“(long)Floor(x)”,则转换可能很大程度上是错误的。
  • 但是请注意,可以用“double”表示的整数值的有效范围非常大,绝对值最大为:(1 + (1 − 2^−52)) × 2 ^1023 ≈ 1.7976931348623157E308;它比“long”的 2^63-1 多得多。但是,可以完全存储的整数范围受到更多限制,因为“双精度”只有 52 位尾数(加上 1 位隐含的最高有效位,未存储),这意味着“双精度”只能存储仅当它们的绝对值低于 2^53 时才使用整数。
  • 不幸的是,如果可能,Math.Floor() 不会在内部使用“Long”返回变量“Number”类型,否则仅用于较大的舍入整数。而标准的数学库不处理这种统一的变量数字类型。存在其他实现统一数字类型的数学库,包括以压缩十进制或二进制编码的 Long、Double 或大整数,而不会丢失支持的范围或精度。

标签: c# math floor


【解决方案1】:

double 的范围远大于intlong 的范围。考虑这段代码:

double d = 100000000000000000000d;
long x = Math.Floor(d); // Invalid in reality

整数超出了long 的范围 - 那么您期望会发生什么?

通常您知道该值将实际上intlong 的范围内,因此您将其转换:

double d = 1000.1234d;
int x = (int) Math.Floor(d);

但该演员的责任在于开发人员,而不是Math.Floor 本身。对于long 范围之外的所有值,如果它只是失败,则会出现不必要的限制。

【讨论】:

  • Floor 返回 double 的整数表示,它返回 double 用于科学计算,这个答案是不正确的,因为 double 有 64 位,long 也有 64 位,但是 double 不能存储精确的低位数字位,即使它可以正确地存储在 long 中。
  • @Jon:你为什么没有参与关于如何在 C# 中使正数为负数的激烈辩论?:stackoverflow.com/questions/1348080/…
  • @Jon:慢慢来。事实证明,社区发现将正数乘以 -1 会使其变为负数。 StackOverflow 上一切正常。
  • @javapowered: 不,(int) 15.0 是 not 0。其他地方出了问题,但我们不知道这是怎么回事。请创建一个简短但完整的程序来演示这一点,然后提出问题。我怀疑你会发现很难复制......
  • @MusiGenesis: (int) IGNORE_RATIO * Volume 计算为 (int) 0.15 * Volume,但类型转换仅适用于比率,不是产品的结果,你得到 0 * Volume 即零!改用 (int)(IGNORE_RATIO * Volume) 来解决您的错误。
【解决方案2】:

根据 MSDN,Math.Floor(double) 返回一个双精度:http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx

如果你想要它作为一个整数:

int result = (int)Math.Floor(yourVariable);

我可以看到 MSDN 文章可能会产生误导,他们应该指定虽然结果是“整数”(在这种情况下表示整数),但它仍然是 TYPE Double

【讨论】:

  • 感谢您的回复。其实我在看这篇文章:msdn.microsoft.com/en-us/library/e0b5f0xb.aspx 但无论如何,我会尝试你的建议。谢谢。
  • 没错,它确实在顶部说“返回一个整数”,但在它下面指定了类型:public static double Floor(double d)
  • integer != int (answers.com/integer) - 整数 可以 存储在 Double 中(请参阅 Jon 的回答),并且有无数个整数不能存储在int
  • Shog,我没说他们不能。我说的是“还是TYPE Double”
  • @Neil:对 - 只是想强调“整数”(集合名称)和 int(类型名称)之间的区别。
【解决方案3】:

如果您只需要数字的整数部分,请将数字转换为 int。这将截断小数点处的数字。

double myDouble = 4.6;
int myInteger = (int)myDouble;

【讨论】:

  • 重要的是要注意,对于负数,转换为 int 的行为与 Floor 不同。 Floor 将始终截断为最大负数,而转换为 int 将截断为 0。
【解决方案4】:

没错。查看声明,Math.Floor(double) 产生一个 double(参见 http://msdn.microsoft.com/en-us/library/e0b5f0xb.aspx)。我假设“整数”是指“整数”。

【讨论】:

    【解决方案5】:

    Floor 将其保留为双精度,因此您可以使用它进行更多双精度计算。 如果您希望它作为 int,请将 floor 的结果转换为 int。 不要将原始的 double 类型转换为 int,因为对于负数而言 floor 的规则是不同的 (IIRC)。

    【讨论】:

      【解决方案6】:
      Convert.ToInt32(Math.Floor(Convert.ToDouble(value)))
      

      如果您将 4.6 返回到 4 作为输出,这将为您提供您想要的确切值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-02
        • 2017-06-15
        • 1970-01-01
        • 2020-08-07
        相关资源
        最近更新 更多