如何四舍五入到最接近的0.5?


102

我必须显示收视率,为此,我需要按如下所述递增:

如果数字是1.0,则应等于1;
如果数字是1.1,则应等于1;
如果数字是1.2,则应等于1;
如果数字是1.3,则应等于1.5;
如果数字是1.4,则应等于1.5
如果数字为1.5,则应等于1.5;
如果数字为1.6,则应等于1.5;
如果数字为1.7,则应等于1.5;
如果数字为1.8,则应等于2.0;
如果数字是1.9,则应等于2.0
如果数字为2.0应等于2.0
如果数字为2.1应等于2.0
依此类推...

是否有一种简单的方法来计算所需的值?


“等等...”是否包括接近最大可表示值的有限数字?
chux-恢复莫妮卡

Answers:


206

将您的评分乘以2,然后使用舍入Math.Round(rating, MidpointRounding.AwayFromZero),然后将该值除以2。

Math.Round(value * 2, MidpointRounding.AwayFromZero) / 2


4
我不需要打字的傻瓜,我不需要打字的聪明人
Neil N

3
不完美!整数溢出呢!您只能计算一半的可能整数。
Elazar Leibovich

2
@Elazar-如果您的排名可以高到1,073,741,823,我想不出一个用例,您会在乎它是“十亿个一半”还是“十亿个”-如果确实有问题那么排名方案就存在固有的缺陷:)
约翰·拉施(John Rasch)2009年

4
先除法,然后相乘。这样可以消除溢出问题,并且还可以四舍五入为任意数。
Benjol

8
@Benjol,先除然后舍入将使它舍入到最接近的2倍,而不是一半。不正确。
Nacht

67

乘以2,取整,然后除以2

如果要最近的四分之一,请乘以4,除以4,以此类推


16

这是我编写的几种方法,它们总是可以向上或向下取整为任何值。

public static Double RoundUpToNearest(Double passednumber, Double roundto)
{
    // 105.5 up to nearest 1 = 106
    // 105.5 up to nearest 10 = 110
    // 105.5 up to nearest 7 = 112
    // 105.5 up to nearest 100 = 200
    // 105.5 up to nearest 0.2 = 105.6
    // 105.5 up to nearest 0.3 = 105.6

    //if no rounto then just pass original number back
    if (roundto == 0)
    {
        return passednumber;
    }
    else
    {
        return Math.Ceiling(passednumber / roundto) * roundto;
    }
}

public static Double RoundDownToNearest(Double passednumber, Double roundto)
{
    // 105.5 down to nearest 1 = 105
    // 105.5 down to nearest 10 = 100
    // 105.5 down to nearest 7 = 105
    // 105.5 down to nearest 100 = 100
    // 105.5 down to nearest 0.2 = 105.4
    // 105.5 down to nearest 0.3 = 105.3

    //if no rounto then just pass original number back
    if (roundto == 0)
    {
        return passednumber;
    }
    else
    {
        return Math.Floor(passednumber / roundto) * roundto;
    }
}

2

有几种选择。如果性能是一个问题,请测试他们以查看哪个在大循环中最快。

double Adjust(double input)
{
    double whole = Math.Truncate(input);
    double remainder = input - whole;
    if (remainder < 0.3)
    {
        remainder = 0;
    }
    else if (remainder < 0.8)
    {
        remainder = 0.5;
    }
    else
    {
        remainder = 1;
    }
    return whole + remainder;
}

这应该可以,但是它不像给出的一些解决方案那样优雅。乘以和使用系统库很简单。
captncraig

性能通常更为重要,与乘法和除法解决方案相比,这可能花费更少的时间。
约翰·费舍尔

3
该代码不正确。由于双精度算术通常具有较小的舍入误差,因此,例如4.8-4.0的运算可能会给出0.799999 ...。在这种情况下,上面的代码将四舍五入为4.5。也最好使用Math.Floor而不是Math.Truncate,因为现在负数没有正确舍入。我更喜欢接受的答案,因为它更简单且更不易实现错误。
ip科2008年

1
decimal d = // your number..

decimal t = d - Math.Floor(d);
if(t >= 0.3d && t <= 0.7d)
{
    return Math.Floor(d) + 0.5d;
}
else if(t>0.7d)
    return Math.Ceil(d);
return Math.Floor(d);

1

听起来您需要四舍五入到最接近的0.5。我看不到任何版本round在C#API中没有看到执行此操作的版本(一个版本需要将十进制数舍入为四舍五入,这是不一样的)。

假设您只需要处理十分之一的整数,就可以计算出round (num * 2) / 2。如果您使用任意精确的小数,它将变得更加棘手。希望您不要。


0

我也有这个问题的困难。我主要使用ActionScript 3.0进行编码,该脚本是Adobe Flash Platform的基本编码,但是这些语言有一些相似之处:

我想出的解决方案如下:

//Code for Rounding to the nearest 0.05
var r:Number = Math.random() * 10;  // NUMBER - Input Your Number here
var n:int = r * 10;   // INTEGER - Shift Decimal 2 places to right
var f:int = Math.round(r * 10 - n) * 5;// INTEGER - Test 1 or 0 then convert to 5
var d:Number = (n + (f / 10)) / 10; //  NUMBER - Re-assemble the number

trace("ORG No: " + r);
trace("NEW No: " + d);

就是这样。注意“数字”和“整数”的使用以及它们的处理方式。

祝好运!


0
Public Function Round(ByVal text As TextBox) As Integer
    Dim r As String = Nothing
    If text.TextLength > 3 Then
        Dim Last3 As String = (text.Text.Substring(text.Text.Length - 3))
        If Last3.Substring(0, 1) = "." Then
            Dim dimcalvalue As String = Last3.Substring(Last3.Length - 2)
            If Val(dimcalvalue) >= 50 Then
                text.Text = Val(text.Text) - Val(Last3)
                text.Text = Val(text.Text) + 1
            ElseIf Val(dimcalvalue) < 50 Then
                text.Text = Val(text.Text) - Val(Last3)
            End If
        End If
    End If
    Return r
End Function

4
这段代码看起来不像问题中想要的C#。它有什么作用?请提供一些解释,而不只是提供一些未指定语言的代码。
AdrianHHH

-1

正确的方法是:

  public static Decimal GetPrice(Decimal price)
            {
                var DecPrice = price / 50;
                var roundedPrice = Math.Round(DecPrice, MidpointRounding.AwayFromZero);
                var finalPrice = roundedPrice * 50;

                return finalPrice;

            }
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.