Menurut dokumentasi, decimal.Round
metode ini menggunakan algoritma round-to-even yang tidak umum untuk sebagian besar aplikasi. Jadi saya selalu berakhir menulis fungsi kustom untuk melakukan algoritma setengah-setengah yang lebih alami:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
Apakah ada yang tahu alasan di balik keputusan desain kerangka kerja ini?
Apakah ada implementasi built-in dari algoritma round-half-up ke dalam kerangka kerja? Atau mungkin beberapa API Windows yang tidak dikelola?
Ini bisa menyesatkan bagi pemula yang hanya menulis decimal.Round(2.5m, 0)
mengharapkan 3 sebagai hasilnya tetapi mendapatkan 2 sebagai gantinya.
Jawaban:
Mungkin karena algoritma yang lebih baik. Selama banyak pembulatan dilakukan, Anda akan rata-rata bahwa semua 0,5 akhirnya sama-sama naik dan turun. Ini memberikan estimasi yang lebih baik dari hasil aktual jika Anda misalnya, menambahkan sekelompok angka bulat. Saya akan mengatakan bahwa meskipun bukan itu yang diharapkan beberapa orang, itu mungkin hal yang lebih benar untuk dilakukan.
sumber
Jawaban yang lain dengan alasan mengapa algoritma Banker (alias setengah putaran ke genap ) adalah pilihan yang baik cukup benar. Itu tidak menderita dari bias negatif atau positif sebanyak setengah putaran dari nol metode atas distribusi yang paling masuk akal.
Tetapi pertanyaannya adalah mengapa .NET menggunakan pembulatan aktual Banker sebagai default - dan jawabannya adalah bahwa Microsoft telah mengikuti standar IEEE 754 . Ini juga disebutkan dalam MSDN untuk Math.Round di bawah Keterangan.
Perhatikan juga bahwa .NET mendukung metode alternatif yang ditentukan oleh IEEE dengan menyediakan
MidpointRounding
enumerasi. Mereka tentu saja dapat memberikan lebih banyak alternatif untuk menyelesaikan ikatan, tetapi mereka memilih untuk hanya memenuhi standar IEEE.sumber
Meskipun saya tidak dapat menjawab pertanyaan "Mengapa desainer Microsoft memilih ini sebagai default?", Saya hanya ingin menunjukkan bahwa fungsi tambahan tidak diperlukan.
Math.Round
memungkinkan Anda menentukanMidpointRounding
:sumber
Desimal sebagian besar digunakan untuk uang ; pembulatan bankir adalah hal biasa ketika bekerja dengan uang . Atau bisa dibilang.
Pembulatan bankir memiliki keuntungan bahwa rata-rata Anda akan mendapatkan hasil yang sama jika Anda:
Pembulatan sebelum dijumlahkan menghemat banyak pekerjaan di hari-hari sebelum komputer.
(Di Inggris ketika kami menggunakan bank desimal tidak akan berurusan dengan setengah pence, tetapi selama bertahun-tahun masih ada koin setengah pence dan toko sering memiliki harga yang berakhir dengan setengah pence - begitu banyak pembulatan)
sumber
Decmial
ya. Desimal, tidak. Untuk anak cucu, saya setuju dengan sentimen asli di sini.Gunakan kelebihan fungsi Round lainnya seperti ini:
Ini akan menghasilkan 3 . Dan jika Anda gunakan
Anda akan mendapatkan pembulatan bankir.
sumber