Wie runde ich auf 0,5?

102

Ich muss Bewertungen anzeigen und dafür benötige ich folgende Schritte:

Wenn die Zahl 1.0 ist, sollte sie gleich 1 sein.
Wenn die Zahl 1.1 ist, sollte sie gleich 1 sein.
Wenn die Zahl 1.2 ist, sollte sie gleich 1 sein.
Wenn die Zahl 1.3 ist, sollte sie gleich 1.5 sein.
Wenn die Zahl 1.4 ist, sollte sie gleich sein 1,5
Wenn die Zahl 1,5 ist, sollte gleich 1,5 sein.
Wenn die Zahl 1,6 gleich 1,5 sein sollte.
Wenn die Zahl 1,7 gleich 1,5 sein sollte.
Wenn die Zahl 1,8 gleich 2,0 sein sollte.
Wenn die Zahl 1,9 gleich sein sollte 2.0
Wenn die Zahl 2.0 ist, sollte gleich 2.0 sein.
Wenn die Zahl 2.1 ist, sollte gleich 2.0 sein
und so weiter ...

Gibt es eine einfache Möglichkeit, die erforderlichen Werte zu berechnen?

Murtaza Mandvi
quelle
"und so weiter ..." beinhaltet das endliche Zahlen nahe dem maximal darstellbaren Wert?
chux

Antworten:

206

Multiplizieren Sie Ihre Bewertung mit 2, runden Sie mit Math.Round(rating, MidpointRounding.AwayFromZero)und dividieren Sie diesen Wert durch 2.

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

John Rasch
quelle
4
Ich muss nicht für Dummies tippen, ich muss für Smarties tippen
Neil N
3
Nicht perfekt! Was ist mit einem Integer-Überlauf? Sie können nur die Hälfte der möglichen Ganzzahlen berechnen.
Elazar Leibovich
2
@Elazar - Wenn Sie bis zu 1.073.741.823 eingestuft werden könnten, kann ich mir keinen einzigen Anwendungsfall vorstellen, bei dem es Sie interessieren würde, ob es "eineinhalb Milliarden" oder "eine Milliarde eine" ist - wenn das wirklich ein Problem ist dann gibt es etwas inhärent fehlerhaft mit dem Ranking-Schema :)
John Rasch
4
Zuerst teilen, dann multiplizieren. Dadurch wird das Überlaufproblem behoben und Sie können auf eine beliebige Zahl runden.
Benjol
8
@Benjol Wenn Sie zuerst teilen und dann runden, wird der nächste Faktor von 2 und nicht der halbe Faktor erreicht. Nicht richtig.
Nacht
67

Mit 2 multiplizieren, runden und dann durch 2 dividieren

Wenn Sie das nächste Viertel wünschen, multiplizieren Sie mit 4, dividieren Sie durch 4 usw.

Neil N.
quelle
16

Hier sind einige Methoden, die ich geschrieben habe und die immer auf einen beliebigen Wert auf- oder abgerundet werden.

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;
    }
}
NER1808
quelle
2

Es gibt mehrere Möglichkeiten. Wenn die Leistung ein Problem darstellt, testen Sie sie, um festzustellen, welche in einer großen Schleife am schnellsten funktioniert.

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;
}
John Fisher
quelle
Dies sollte funktionieren, ist aber nicht so elegant wie einige Lösungen. Das Multiplizieren und Verwenden der Systembibliothek ist einfach sexy.
Captncraig
Die Leistung ist normalerweise wichtiger, und dies kann weniger Zeit in Anspruch nehmen als die Multiplikations- und Divisionslösungen.
John Fisher
3
Dieser Code ist nicht korrekt. Da Arithmetik mit Doubles normalerweise einige kleine Rundungsfehler aufweist, könnte eine Operation wie 4.8 - 4.0 beispielsweise 0.799999 .... ergeben. In diesem Fall würde der obige Code auf 4,5 runden. Besser wäre es auch, Math.Floor anstelle von Math.Truncate zu verwenden, da negative Zahlen derzeit nicht korrekt gerundet sind. Ich bevorzuge die akzeptierte Antwort, da sie einfacher und weniger anfällig für Implementierungsfehler ist.
Accipitridae
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);
Akash Kava
quelle
1

Klingt so, als müssten Sie auf 0,5 runden. Ich sehe keine Version von roundin der C # -API, die dies tut (eine Version benötigt eine Anzahl von Dezimalstellen zum Runden, was nicht dasselbe ist).

Angenommen, Sie müssen sich nur mit ganzzahligen Zehntelzahlen befassen, reicht die Berechnung aus round (num * 2) / 2. Wenn Sie beliebig genaue Dezimalstellen verwenden, wird es schwieriger. Hoffen wir, dass Sie es nicht tun.

Paul Brinkley
quelle
0

Ich hatte auch Schwierigkeiten mit diesem Problem. Ich codiere hauptsächlich in Actionscript 3.0, der Basiscodierung für die Adobe Flash-Plattform, aber es gibt Ähnlichkeiten in den Sprachen:

Die Lösung, die ich gefunden habe, ist die folgende:

//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);

Das wars so ziemlich. Beachten Sie die Verwendung von 'Zahlen' und 'Ganzzahlen' und die Art und Weise, wie sie verarbeitet werden.

Viel Glück!

Jason Henn
quelle
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
user2260011
quelle
4
Dieser Code sieht nicht wie in der Frage gewünscht wie C # aus. Was tut es? Bitte geben Sie eine Erklärung und nicht nur einen Codeklumpen in einer nicht angegebenen Sprache.
AdrianHHH
-1

Der richtige Weg, dies zu tun, ist:

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

                return finalPrice;

            }
Carca
quelle