为什么Math.Floor(Double)返回Double类型的值?


103

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


2
MSDN文档说它返回一个整数值MSDN文档指出Math.Floor返回System.Double,而不是整数。
宽带

有效地需要一个整数值,但这并不意味着它可以存储为“ int”或“ long”。一个“双精度”成功地将所有整数值存储在一个比“ int”宽得多的范围内。请注意,当尾数部分的位数为2时,尾数部分的位数不足以存储整数值的所有数字时,可能会舍入某些整数值超过52:对于大于2 ^ 52或小于-2 ^ 52的整数,可能会发生“双精度”整数值的四舍五入,但结果仍将是可表示的最接近的整数;如果使用“(long)Floor(x)”,则转换可能在很大程度上是错误的。
verdy_p 2015年

但是请注意,可以用“ double”表示的整数值的有效范围非常大,其绝对值最高为:(1 +(1 − 2 ^ -52))×2 ^ 1023≈1.7976931348623157E308; 它远远超过2 ^ 63-1中的“ long”。但是,可以全部存储的整数范围受到更大限制,因为“双精度”尾数只有52位(加上最高有效位隐含的1位,未存储),这意味着“双精度”只能存储当其绝对值小于2 ^ 53时,整数恰好为整数。
verdy_p

不幸的是,如果可能的话,Math.Floor()不会在内部使用“ Long”返回变量“ Number”类型,否则仅对大的舍入整数不返回“ Double”。而且标准的数学库不处理这种统一的变量数字类型。还存在其他实现统一数字类型的数学库,包括以压缩十进制或二进制编码的Long,Double或大整数,而不会损失支持的范围或精度。
verdy_p

Answers:


146

的范围doubleint或的范围宽得多long。考虑以下代码:

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

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

通常,您知道该值实际上int或范围内long,因此您将其强制转换为:

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

但是该转换的责任在于开发者,而不是Math.Floor自身。要使它仅发生故障,并且对范围之外的所有值都有例外,将有不必要的限制long


2
Floor返回double的整数表示形式,并且为科学计算返回double,这个答案是不正确的,因为double具有64位,而long也具有64位,但是double不能存储较低有效位的确切数字,即使可以正确存储长。
阿卡什·卡瓦

1
@Jon:关于如何在C#中使正数变为负数的争论,您怎么没想到呢?:stackoverflow.com/questions/1348080/…–
MusiGenesis

3
@Jon:慢慢来。事实证明,社区发现将正数乘以-1将使其为负。一切在StackOverflow上都很好。
MusiGenesis

1
@javapowered:不,(int)15.0 为0。其他地方出了问题,但是我们不能仅凭此判断。请创建一个简短但完整的程序来演示此操作,然后提出一个问题。我怀疑您会很难复制...
Jon Skeet 2012年

1
@MusiGenesis:<code>(int)IGNORE_RATIO *体积</ code>计算为<code>(int)0.15 * Volume </ code>,但类型转换仅适用于比率,而不适用于乘积结果,并且您得到<code> 0 * Volume </ code>,即零!使用<code>(int)(IGNORE_RATIO * Volume)</ code>来解决您的错误。
verdy_p

11

根据MSDN,Math.Floor(double)返回一个双精度值:http : //msdn.microsoft.com/zh-cn/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)
Neil N

3
整数!= intanswers.com/integer)-整数可以存储在中Double(请参阅乔恩的答案),并且有无限数量的整数不能存储在中int
Shog9

Shog,我没有说他们做不到。我所说的是“仍然是Double型”
Neil N

1
@Neil:对-只是想强调“整数”(集合的int名称)和(类型的名称)之间的区别。
Shog9年9

4

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

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

2
重要的是要注意,对于负数,强制转换为与的int行为不同FloorFloor总是会截断最负数,而铸造int将截断向0
马格努斯


0

Floor将其保留为double,因此您可以使用它进行更多double计算。如果希望将其作为整数,则将floor的结果强制转换为整数。不要将原始的双精度数转换为int值,因为负数的下限规则(IIRC)不同。


0
Convert.ToInt32(Math.Floor(Convert.ToDouble(value)))

如果将4.64作为输出返回,则将为您提供所需的确切值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.