Bagaimana cara membulatkan ke 0,5 terdekat?

102

Saya harus menampilkan peringkat dan untuk itu saya perlu kenaikan sebagai berikut:

Jika angkanya 1.0 harus sama dengan 1
Jika angkanya 1.1 harus sama dengan 1
Jika angkanya 1.2 harus sama dengan 1
Jika nomor 1.3 harus sama dengan 1.5
Jika nomor 1.4 harus sama dengan 1.5
Jika angka 1.5 harus sama dengan 1.5
Jika angka 1.6 harus sama dengan 1.5
Jika angka 1.7 harus sama dengan 1.5
Jika angka 1.8 harus sama dengan 2.0
Jika angka 1.9 harus sama dengan 2.0
Jika angka 2.0 harus sama dengan 2.0
Jika angka 2.1 harus sama dengan 2.0
dan seterusnya ...

Apakah ada cara sederhana untuk menghitung nilai yang dibutuhkan?

Murtaza Mandvi
sumber
"dan seterusnya ..." apakah itu termasuk angka terbatas yang mendekati nilai maksimum yang dapat diwakili?
chux

Jawaban:

206

Kalikan peringkat Anda dengan 2, lalu bulatkan menggunakan Math.Round(rating, MidpointRounding.AwayFromZero), lalu bagi nilainya dengan 2.

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

John Rasch
sumber
4
Saya tidak perlu mengetik untuk boneka, saya perlu mengetik untuk smarties
Neil N
3
Tidak sempurna! bagaimana dengan integer overflow! Anda hanya dapat menghitung setengah dari kemungkinan bilangan bulat.
Elazar Leibovich
2
@Elazar - jika Anda dapat peringkat setinggi 1.073.741.823, saya tidak dapat memikirkan satu kasus penggunaan di mana Anda akan peduli apakah itu "satu miliar satu setengah" atau "satu miliar satu" - jika itu benar-benar masalah maka ada sesuatu yang secara inheren cacat dengan skema peringkat :)
John Rasch
4
Bagilah dulu, lalu kalikan. Ini akan menghilangkan masalah luapan, dan juga memungkinkan Anda untuk membulatkan ke angka acak.
Benjol
8
@Benjol, membagi pertama dan kemudian pembulatan akan menyebabkannya membulatkan ke faktor terdekat 2, bukan faktor satu setengah. Tidak benar.
Nacht
67

Kalikan dengan 2, bulatkan, lalu bagi dengan 2

jika Anda ingin kuarter terdekat, kalikan dengan 4, bagi dengan 4, dst

Neil N
sumber
16

Berikut adalah beberapa metode yang saya tulis yang akan selalu membulatkan ke atas atau ke bawah ke nilai apa pun.

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
sumber
2

Ada beberapa pilihan. Jika kinerja menjadi perhatian, uji mereka untuk melihat mana yang bekerja paling cepat dalam loop besar.

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
sumber
Ini seharusnya berhasil, tetapi tidak seanggun beberapa solusi yang diberikan. Mengalikan dan menggunakan perpustakaan sistem itu seksi.
captncraig
Performa biasanya lebih penting, dan ini bisa memakan waktu lebih sedikit daripada solusi perkalian dan pembagian.
John Fisher
3
Kode ini salah. Karena aritmatika dengan penggandaan biasanya memiliki beberapa kesalahan pembulatan kecil, operasi seperti 4,8 - 4,0 dapat menghasilkan misalnya 0,799999 .... Dalam hal ini kode di atas akan dibulatkan menjadi 4,5. Juga lebih baik menggunakan Math.Floor daripada Math.Truncate, karena saat ini bilangan negatif tidak dibulatkan dengan benar. Saya lebih suka jawaban yang diterima, karena lebih sederhana dan tidak terlalu rentan terhadap kesalahan implementasi.
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
sumber
1

Sepertinya Anda perlu membulatkan ke 0,5 terdekat. Saya tidak melihat versiround di C # API yang melakukan ini (satu versi membutuhkan sejumlah digit desimal untuk dibulatkan, yang bukan hal yang sama).

Dengan asumsi Anda hanya harus berurusan dengan bilangan bulat persepuluhan, itu sudah cukup untuk menghitung round (num * 2) / 2. Jika Anda menggunakan desimal yang tepat sewenang-wenang, itu menjadi lebih rumit. Semoga tidak.

Paul Brinkley
sumber
0

Saya mengalami kesulitan dengan masalah ini juga. Saya membuat kode terutama di Actionscript 3.0 yang merupakan pengkodean dasar untuk Platform Adobe Flash, tetapi ada simularitas dalam Bahasa:

Solusi yang saya dapatkan adalah sebagai berikut:

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

Cukup banyak. Catat penggunaan 'Angka' dan 'Bilangan bulat' dan cara pemrosesannya.

Semoga berhasil!

Jason Henn
sumber
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
pengguna2260011
sumber
4
Kode ini tidak terlihat seperti C # seperti yang diinginkan dalam pertanyaan. Apa fungsinya? Berikan beberapa penjelasan, bukan hanya sekumpulan kode dalam bahasa yang tidak ditentukan.
AdrianHHH
-1

Cara yang benar untuk melakukannya adalah:

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

                return finalPrice;

            }
Carca
sumber