En yakın 0,5'e nasıl yuvarlayabilirim?


103

Derecelendirmeleri göstermem gerekiyor ve bunun için aşağıdaki gibi artışlara ihtiyacım var:

Sayı 1.0 ise 1'e eşit olmalıdır
Sayı 1.1 ise 1'e eşit olmalıdır
Sayı 1.2 ise 1'e eşit olmalıdır
Sayı 1.3 ise 1.5'e eşit olmalıdır
Eğer 1.4 ise eşit olmalıdır 1.5
Sayı 1.5 ise 1.5 eşit
olmalı 1.6
Sayı 1.7 ise 1.5
eşit olmalı 1.8 sayı 1.8 ise 2.0
eşit olmalı 1.9 sayı ise eşit olmalıdır 2.0
Sayı 2.0 ise 2.0'a eşit olmalıdır
Sayı 2.1 ise 2.0'a eşit olmalı
vb.

Gerekli değerleri hesaplamanın basit bir yolu var mı?


"vesaire ..." bu maksimum gösterilebilir değere yakın sonlu sayıları içeriyor mu?
chux -

Yanıtlar:


208

Puanınızı 2 ile çarpın, ardından kullanarak yuvarlayın ve Math.Round(rating, MidpointRounding.AwayFromZero)bu değeri 2'ye bölün.

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


4
Aptallar için yazmaya ihtiyacım yok, akıllılar için yazmaya ihtiyacım var
Neil N

3
Mükemmel değil! peki ya tamsayı taşması! Olası tam sayıların yalnızca yarısını hesaplayabilirsiniz.
Elazar Leibovich

2
@Elazar - 1.073.741.823. sırada yer alabilseydiniz, "bir milyar bir buçuk" veya "bir milyar bir" olmasını umursayacağınız tek kullanımlık bir durum düşünemiyorum - eğer bu gerçekten bir sorunsa sıralama şemasında doğası gereği kusurlu bir şey var :)
John Rasch

4
Önce bölün, sonra çarpın. Bu, taşma sorununu ortadan kaldıracak ve ayrıca rastgele bir sayıya yuvarlamanıza izin verecektir.
Benjol

8
@Benjol, önce bölmek ve sonra yuvarlamak, yarım çarpan yerine en yakın 2 çarpana yuvarlanmasına neden olur. Doğru değil.
Nacht

66

2 ile çarpın, yuvarlayın, sonra 2'ye bölün

en yakın çeyrek istiyorsanız, 4 ile çarpın, 4'e bölün, vb.


16

İşte yazdığım ve her zaman herhangi bir değere yuvarlayacak veya aşağı yuvarlayacak birkaç yöntem.

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

Birkaç seçenek var. Performans önemliyse, hangisinin büyük bir döngüde en hızlı çalıştığını görmek için onları test edin.

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

Bu işe yaramalı, ancak verilen bazı çözümler kadar zarif değil. Sistem kitaplığını çoğaltmak ve kullanmak çok seksi.
captncraig

Performans genellikle daha önemlidir ve bu, çarpma ve bölme çözümlerinden daha az zaman alabilir.
John Fisher

3
Bu kod doğru değil. Çiftli aritmetik genellikle bazı küçük yuvarlama hatalarına sahip olduğundan, 4.8 - 4.0 gibi bir işlem örneğin 0.799999 ... verebilir. Bu durumda yukarıdaki kod 4.5'e yuvarlanır. Ayrıca Math.Truncate yerine Math.Floor kullanmak daha iyidir, çünkü şu anda negatif sayılar doğru şekilde yuvarlanmamaktadır. Kabul edilen yanıtı tercih ederim çünkü daha basittir ve uygulama hatalarına daha az eğilimlidir.
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);

1

En yakın 0,5'e yuvarlamanız gerekiyor gibi görünüyor. roundC # API'sinde bunu yapan hiçbir sürüm görmüyorum (bir sürüm, yuvarlamak için birkaç ondalık basamak alır, bu aynı şey değildir).

Yalnızca onda birlik tam sayılarla uğraşmanız gerektiğini varsayarsak, hesaplamak yeterlidir round (num * 2) / 2. Rasgele kesinlikli ondalık sayılar kullanıyorsanız, daha karmaşık hale gelir. Umarım yapmazsın.


0

Bu problemde de zorluk çektim. Esas olarak Adobe Flash Platform için temel kodlama olan Actionscript 3.0 ile kodluyorum, ancak Dillerdeki benzerlikler var:

Bulduğum çözüm şu:

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

Hepsi bukadar. "Sayılar" ve "Tamsayılar" ın kullanımına ve bunların nasıl işlendiğine dikkat edin.

İyi şanslar!


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

5
Bu kod, soruda istendiği gibi C # gibi görünmüyor. Bu ne işe yarıyor? Lütfen belirtilmemiş bir dilde bir yığın kod yerine biraz açıklama sağlayın.
AdrianHHH

-1

Bunu yapmanın doğru yolu şudur:

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

                return finalPrice;

            }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.