如何将双精度数转换为最接近的整数值?


Answers:


78

Math.round()结合使用,可能与MidpointRounding.AwayFromZero

例如:

Math.Round(1.2) ==> 1
Math.Round(1.5) ==> 2
Math.Round(2.5) ==> 2
Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3

6
不会Convert.ToInt32()做同样的事情,还是只是在小数点后去除所有内容?
松饼人

208
实际上不产生整数,而是产生双精度数。
gatopeich

13
@Ronnie-不,这是设计使然。默认情况下,Math.Round会将中点数字(x + .5)舍入到最接近的偶数。如果您想要其他行为,则必须通过标志来指定。msdn.microsoft.com/zh-cn/library/system.midpointrounding.aspx
nickf 2012年

6
嗯,我从来没有!:)
罗尼2012年

5
Double不是Int。
伊夫根尼·纳博科夫

267
double d = 1.234;
int i = Convert.ToInt32(d);

参考

这样处理舍入:

舍入到最接近的32位有符号整数。如果值在两个整数之间,则返回偶数;否则,返回偶数。即4.5转换为4,5.5转换为6。


7
更好的是Math.Round,它根据需要返回int。
基思

10
@ robert-koritnik。不知道为什么那是“无效的”。OP没有指定首选的舍入规则,并且“ .5到最接近的偶数舍入”是从回溯开始的标准规则。始终四舍五入会产生有害的统计影响。
基思(Keith)

@Keith:我不知道,但是我一直被教导要对x.5进行四舍五入,但是我可以看到进行统计的理由。感谢那。附言:很明显,我不在统计,财务或会计领域,这种舍入似乎是默认的
罗伯特·科里特尼克

3
“总是四舍五入会产生有害的统计影响”-这完全是错误的。将.5向上四舍五入正好舍入一半的数字-- [0,.5)向下,正好舍入一半的数字[.5,1)--向上。四舍五入到稍微偏置偶数,因为它四舍五入(.5,1.5)到1,但[1.5,2.5]到2
吉姆·巴尔特

11
@JimBalter由于不对零进行舍入,因此将一半舍入会引入正偏差,因此称为不对称舍入。如果您的分布足够均匀,并且舍入不偏向于偶数或不均匀数,则“半舍入到偶数”就不会。请参见中途四舍五入
2014年

36

您还可以使用功能:

//Works with negative numbers now
static int MyRound(double d) {
  if (d < 0) {
    return (int)(d - 0.5);
  }
  return (int)(d + 0.5);
}

根据体系结构,它要快几倍。


这对我来说很完美,因为Math.Round并没有按照我想要的方式工作。
汉娜(Hanna)2012年

@cullub是的。它将附加了0.5的double d转换为整数。
Darrell 2014年

这是我的首选方法-以非常简单的方式工作。比Math.Round(d,MidpointRounding.AwayFromZero)短得多,而且更易于阅读,比使用if语句选择舍入还是舍入更简洁。AND,实际上在末尾返回一个整数,而不是一个双数
绑定

3
有关负数(MyRound(-1.2)= 0)的奇数行为,请参见下面的@ Eternal21注释
Chris

2
对于任何想知道的人,现在可以通过检查值是否为负来解决@Chris提到的问题。
约翰·威茨

14
double d;
int rounded = (int)Math.Round(d);

5

我知道这个问题很旧,但是在寻找类似问题的答案时遇到了它。我以为我会分享给我的非常有用的提示。

转换为int时,只需.5在向下转换前添加您的值即可。由于向下转换int始终下降到较低的数字(例如(int)1.7 == 1),因此,如果您的数字大于或等于该数字,则.5添加.5将其带入下一个数字,而向下转换至的数字int应返回正确的值。(例如(int)(1.8 + .5) == 2


13
问题是如果您尝试以这种方式转换负值。例如,-1.25最终等于0。(-1.25 + 0.5 = 0.75,并且一旦转换为整数,它就是0)。因此,您需要从负值中减去0.5。
Eternal21

一个人可以使用+ 0.5 * Math.Abs(d)
TaW


-1

对于Unity,请使用Mathf.RoundToInt

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.0f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.2f));
        // Prints 11
        Debug.Log(Mathf.RoundToInt(10.7f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.5f));
        // Prints 12
        Debug.Log(Mathf.RoundToInt(11.5f));

        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.0f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.2f));
        // Prints -11
        Debug.Log(Mathf.RoundToInt(-10.7f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.5f));
        // Prints -12
        Debug.Log(Mathf.RoundToInt(-11.5f));
    }
}

资源

public static int RoundToInt(float f) { return (int)Math.Round(f); }

Q没有提及或标记Unity。
XenoRo

@XenoRo我为那些使用Unity时寻找相似答案的人回答了这个老问题。
zwcloud

2
您可以回答自己的问题以进行知识共享。在这种情况下,请针对API(在本例中为Unity)创建一个单独的问题。答案应该适合于这些问题。否则,对于每个带有舍入功能的C#API,都可能会有一个答案。
XenoRo

-2

我正在开发一款具有Int按钮的科学计算器。我发现以下是一个简单,可靠的解决方案:

double dblInteger;
if( dblNumber < 0 )
   dblInteger = Math.Ceiling(dblNumber);
else
   dblInteger = Math.Floor(dblNumber);

Math.Round有时会产生意外或不希望的结果,并且显式转换为整数(通过强制转换或Convert.ToInt ...)通常会为更高的数字产生错误的值。上面的方法似乎总是可行。


2
这不是将所有负数都四舍五入吗?不一定是“最整洁的”整数。
蒂姆·波曼

这不是最近的数字。
Samer Aamar

1
给定1.99,则返回1.0。
乔恩·施耐德
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.