Rupanya metode putaran, ketika diminta untuk membulatkan angka persis antara dua bilangan bulat, mengembalikan bilangan bulat genap. Jadi, Math.Round (3.5) mengembalikan 4. Lihat artikel ini
SQL Server berputar seperti itu; hasil tes menarik ketika ada tes unit C # ti memvalidasi pembulatan dilakukan dalam T-SQL.
idstam
7
@ nama itu bukan bug. Ini adalah cara floating point biner bekerja. 1.005tidak dapat direpresentasikan secara persis ganda. Itu mungkin 1.00499.... Jika Anda menggunakan Decimalmasalah ini akan hilang. Keberadaan Math.Round berlebihan yang mengambil sejumlah digit desimal pada dobel adalah pilihan desain IMO yang meragukan, karena jarang akan bekerja dengan cara yang bermakna.
CodesInChaos
Jawaban:
561
Pertama, ini bukan bug C # - itu akan menjadi bug .NET. C # adalah bahasanya - tidak memutuskan bagaimana Math.Rounddiimplementasikan.
Dan kedua, tidak - jika Anda membaca dokumen , Anda akan melihat bahwa pembulatan standar adalah "pembulatan ke genap" (pembulatan bankir):
Return Value Type: System.Double Integer terdekat a. Jika komponen fraksional dari a adalah setengah antara dua bilangan bulat, salah satunya genap dan yang lain ganjil, maka bilangan genap dikembalikan. Perhatikan bahwa metode ini mengembalikan tipe Doublebukan integral.
Keterangan Perilaku metode ini mengikuti IEEE Standard 754, bagian 4. Pembulatan semacam ini kadang-kadang disebut pembulatan ke terdekat, atau pembulatan bankir. Ini meminimalkan kesalahan pembulatan yang dihasilkan dari pembulatan nilai titik tengah secara konsisten dalam satu arah.
Anda dapat menentukan bagaimana Math.Roundseharusnya membulatkan titik tengah menggunakan kelebihan yang mengambil MidpointRoundingnilai. Ada satu kelebihan dengan yang MidpointRoundingterkait dengan masing-masing kelebihan yang tidak memilikinya:
Apakah default ini dipilih dengan baik atau tidak adalah masalah yang berbeda. ( MidpointRoundinghanya diperkenalkan di .NET 2.0. Sebelum itu saya tidak yakin ada cara mudah untuk menerapkan perilaku yang diinginkan tanpa melakukannya sendiri.) Secara khusus, sejarah telah menunjukkan bahwa itu bukan perilaku yang diharapkan - dan dalam kebanyakan kasus itu adalah dosa utama dalam desain API. Saya bisa melihat mengapa Pembulatan Banker berguna ... tetapi masih mengejutkan banyak orang.
Anda mungkin tertarik untuk melihat enum ( RoundingMode) yang setara dengan Java terdekat yang menawarkan lebih banyak opsi. (Itu tidak hanya berurusan dengan titik tengah.)
saya tidak tahu apakah ini bug, saya pikir itu adalah desain sejak 0,5 adalah sedekat dengan bilangan bulat terendah terdekat dengan bilangan bulat tertinggi terdekat.
Stan R.
3
Saya ingat perilaku ini di VB sebelum .NET diterapkan.
John Fiala
7
Memang, IEEE Standard 754, bagian 4 sebagai negara dokumentasi.
Jon Skeet
2
Saya terbakar oleh ini beberapa waktu yang lalu dan berpikir itu adalah kegilaan belaka juga. Untungnya mereka menambahkan cara untuk menentukan pembulatan yang kita semua pelajari di sekolah dasar; MidPointRounding.
Shea
26
+1 untuk "itu bukan perilaku yang diharapkan [...] itu adalah dosa utama dalam desain API"
BlueRaja - Danny Pflughoeft
215
Itu disebut pembulatan ke genap (atau pembulatan bankir), yang merupakan strategi pembulatan yang valid untuk meminimalkan kesalahan dalam jumlah (MidpointRounding.ToEven). Teorinya adalah bahwa, jika Anda selalu membulatkan angka 0,5 ke arah yang sama, kesalahan akan bertambah lebih cepat (round-to-even seharusnya meminimalkan itu) (a) .
Ikuti tautan ini untuk deskripsi MSDN tentang:
Math.Floor, yang membulatkan ke arah infinity negatif.
Math.Ceiling, yang dibulatkan ke arah infinity positif.
Math.Truncate, yang membulatkan ke atas atau ke bawah menuju nol.
Math.Round, yang membulatkan ke bilangan bulat terdekat atau jumlah tempat desimal yang ditentukan. Anda dapat menentukan perilaku jika persis sama antara dua kemungkinan, seperti pembulatan sehingga angka akhir genap (" Round(2.5,MidpointRounding.ToEven)" menjadi 2) atau sehingga jauh dari nol (" Round(2.5,MidpointRounding.AwayFromZero)" menjadi 3).
Diagram dan tabel berikut dapat membantu:
-3-2-10123+--|------+---------+----|----+--|------+----|----+-------|-+
a b c d e
a=-2.7 b=-0.5 c=0.3 d=1.5 e=2.8===========================Floor-3-1012Ceiling-20123Truncate-20012Round(ToEven)-30023Round(AwayFromZero)-3-1023
Perhatikan bahwa Roundjauh lebih kuat daripada yang terlihat, hanya karena dapat membulatkan ke tempat desimal tertentu. Semua yang lain membulatkan ke nol desimal selalu. Sebagai contoh:
n =3.145;
a =System.Math.Round(n,2,MidpointRounding.ToEven);// 3.14
b =System.Math.Round(n,2,MidpointRounding.AwayFromZero);// 3.15
Dengan fungsi-fungsi lain, Anda harus menggunakan tipuan multiply / bagi untuk mendapatkan efek yang sama:
c =System.Math.Truncate(n *100)/100;// 3.14
d =System.Math.Ceiling(n *100)/100;// 3.15
(a) Tentu saja, teori itu tergantung pada fakta bahwa data Anda memiliki penyebaran nilai yang merata di belahan genap (0,5, 2.5, 4.5, ...) dan setengah aneh (1,5, 3,5, ...).
Jika semua "nilai setengah" adalah genap (misalnya), kesalahan akan terakumulasi secepat jika Anda selalu dibulatkan ke atas.
Penjelasan yang bagus! Saya ingin melihat sendiri bagaimana kesalahan terakumulasi dan saya menulis sebuah skrip yang menunjukkan bahwa nilai dibulatkan menggunakan pembulatan bankir, dalam jangka panjang, memiliki jumlah dan rata-rata mereka lebih dekat dengan nilai-nilai asli. github.com/AmadeusW/RoundingDemo (gambar plot tersedia)
Amadeusz Wieczorek
Hanya beberapa saat setelahnya: bukankah seharusnya ecentang (= 2.8) lebih baik dari pada 2centang?
superjos
Cara mudah untuk mengingat, dan mengasumsikan tempat persepuluhan adalah 5: - tempat dan kesepuluh semuanya ganjil = bulat - tempat dan kesepuluh bercampur = bulat bawah * Nol tidak aneh * Dibalik untuk angka negatif
Arkham Angel
@ArkhamAngel, itu sepertinya benar-benar lebih sulit untuk diingat daripada hanya "membuat angka terakhir" :-)
Bilangan bulat terdekat a. Jika komponen fraksional dari a adalah setengah antara dua bilangan bulat, salah satunya genap dan yang lain ganjil, maka bilangan genap dikembalikan.
... dan 2.5, berada di tengah-tengah antara 2 dan 3, dibulatkan ke angka genap (2). ini disebut Pembulatan Banker (atau round-to-even), dan merupakan standar pembulatan yang umum digunakan.
Artikel MSDN yang sama:
Perilaku metode ini mengikuti IEEE Standard 754, bagian 4. Pembulatan semacam ini kadang-kadang disebut pembulatan ke terdekat, atau pembulatan bankir. Ini meminimalkan kesalahan pembulatan yang dihasilkan dari pembulatan nilai titik tengah secara konsisten dalam satu arah.
Anda dapat menentukan perilaku pembulatan yang berbeda dengan memanggil kelebihan Math.Round yang mengambil MidpointRoundingmode.
Perilaku metode ini mengikuti IEEE Standard 754, bagian 4. Pembulatan semacam ini kadang-kadang disebut pembulatan ke terdekat, atau pembulatan bankir.
Anda dapat menentukan perilaku Math.Roundmenggunakan kelebihan:
Pertimbangkan tugas pembulatan bilangan yang berisi sebagian kecil, misalnya, bilangan bulat. Proses pembulatan dalam keadaan ini adalah untuk menentukan bilangan bulat mana yang paling tepat mewakili bilangan yang Anda bulatkan.
Secara umum, atau pembulatan 'aritmatika', jelas bahwa putaran 2.1, 2.2, 2.3 dan 2.4 menjadi 2.0; dan 2.6, 2.7, 2.8 dan 2.9 hingga 3.0.
Itu berarti 2.5, yang tidak lebih dekat ke 2.0 daripada ke 3.0. Terserah Anda untuk memilih antara 2.0 dan 3.0, keduanya akan sama-sama valid.
Untuk angka minus, -2.1, -2.2, -2.3 dan -2.4, akan menjadi -2.0; dan -2.6, 2.7, 2.8 dan 2.9 akan menjadi -3.0 di bawah pembulatan aritmatika.
Untuk -2.5 dibutuhkan pilihan antara -2.0 dan -3.0.
Bentuk pembulatan lainnya
'Pembulatan' mengambil angka apa pun dengan tempat desimal dan menjadikannya nomor 'keseluruhan' berikutnya. Dengan demikian, tidak hanya 2,5 dan 2,6 putaran ke 3,0, tetapi begitu juga 2,1 dan 2,2.
Pembulatan memindahkan angka positif dan negatif dari nol. Misalnya. 2,5 hingga 3,0 dan -2,5 hingga -3,0.
'Membulatkan ke bawah' memotong angka dengan memotong angka yang tidak diinginkan. Ini memiliki efek memindahkan angka ke nol. Misalnya. 2,5 hingga 2,0 dan -2,5 hingga -2,0
Dalam "pembulatan bankir" - dalam bentuknya yang paling umum - .5 yang akan dibulatkan dibulatkan ke atas atau ke bawah sehingga hasil pembulatan selalu berupa bilangan genap. Jadi 2,5 putaran ke 2.0, 3.5 ke 4.0, 4.5 ke 4.0, 5.5 ke 6.0, dan seterusnya.
'Alternate rounding' sebagai pengganti proses untuk 0,5 antara pembulatan ke bawah dan pembulatan ke atas.
'Pembulatan acak' melingkar .5 ke atas atau ke bawah secara acak.
Simetri dan asimetri
Fungsi pembulatan dikatakan 'simetris' jika ia membulatkan semua angka dari nol atau membulatkan semua angka ke nol.
Fungsi adalah 'asimetris' jika membulatkan angka positif ke nol dan angka negatif menjauh dari nol .. Misalnya. 2,5 hingga 2,0; dan -2,5 hingga -3,0.
Juga asimetris adalah fungsi yang membulatkan angka positif dari nol dan angka negatif ke nol. Misalnya. 2,5 hingga 3,0; dan -2,5 hingga -2,0.
Sebagian besar waktu orang berpikir tentang pembulatan simetris, di mana -2.5 akan dibulatkan ke -3.0 dan 3.5 akan dibulatkan ke 4.0. (dalam C #Round(AwayFromZero))
Defaultnya MidpointRounding.ToEven, atau pembulatan Bankir ( 2,5 menjadi 2, 4,5 menjadi 4 dan seterusnya ) telah menyengat saya sebelumnya dengan menulis laporan untuk akuntansi, jadi saya akan menulis beberapa kata dari apa yang saya temukan, sebelumnya dan dari melihat ke dalamnya untuk posting ini.
Siapa saja bankir yang mengumpulkan angka genap (mungkin bankir Inggris!)?
Dari wikipedia
Asal usul istilah pembulatan bankir masih lebih jelas. Jika metode pembulatan ini pernah menjadi standar dalam perbankan, bukti telah terbukti sangat sulit ditemukan. Sebaliknya, bagian 2 dari laporan Komisi Eropa Pengenalan Euro dan Jumlah Pembulatan Mata Uang menunjukkan bahwa sebelumnya tidak ada pendekatan standar untuk pembulatan di perbankan; dan itu menentukan bahwa jumlah "setengah jalan" harus dibulatkan.
Tampaknya cara pembulatan yang sangat aneh terutama untuk perbankan, kecuali tentu saja bank menggunakan untuk menerima banyak simpanan dalam jumlah genap. Setor £ 2,4 juta, tapi kami akan menyebutnya £ 2 juta, pak.
Standar IEEE 754 tanggal kembali ke 1985 dan memberikan kedua cara pembulatan, tetapi dengan bankir sebagai yang direkomendasikan oleh standar. Ini artikel wikipedia memiliki daftar panjang tentang bagaimana bahasa menerapkan pembulatan (saya benar jika salah satu di bawah salah) dan yang paling tidak menggunakan Bankers' tetapi pembulatan Anda diajarkan di sekolah:
Putaran C / C ++ () dari math.h putaran jauh dari nol (bukan pembulatan bankir)
Java Math. Putaran bulat dari nol (itu lantai hasilnya, menambahkan 0,5, dilemparkan ke bilangan bulat). Ada alternatif di BigDecimal
Terima kasih untuk informasi. Saya tidak pernah menyadari ini. Contoh Anda tentang jutaan ejekan itu sedikit, tetapi bahkan jika Anda membulatkan sen, harus membayar bunga pada 10 juta rekening bank akan banyak biaya bank jika semua setengah sen dibulatkan, atau akan banyak biaya klien jika semua setengah sen dibulatkan ke bawah. Jadi saya bisa membayangkan ini adalah standar yang disepakati. Tidak yakin apakah ini benar-benar digunakan oleh para bankir. Sebagian besar pelanggan tidak akan melihat pembulatan, sambil membawa banyak uang, tapi saya bisa membayangkan ini diwajibkan oleh undang-undang jika Anda tinggal di negara dengan undang
Harald Coppoolse
15
Dari MSDN:
Secara default, Math.Round menggunakan MidpointRounding.ToEven. Kebanyakan orang tidak terbiasa dengan "pembulatan ke genap" sebagai alternatif, "pembulatan dari nol" lebih umum diajarkan di sekolah. .NET default ke "Pembulatan ke genap" karena secara statistik lebih unggul karena tidak berbagi kecenderungan "pembulatan dari nol" untuk mengumpulkan sedikit lebih sering daripada membulatkan ke bawah (dengan asumsi angka yang dibulatkan cenderung positif. )
Saya punya masalah ini di mana server SQL saya mengumpulkan 0,5 hingga 1 sedangkan aplikasi C # saya tidak. Jadi, Anda akan melihat dua hasil yang berbeda.
Inilah implementasi dengan int / long. Ini adalah bagaimana putaran Jawa.
int roundedNumber =(int)Math.Floor(d +0.5);
Ini mungkin metode yang paling efisien yang dapat Anda pikirkan juga.
Jika Anda ingin membuatnya ganda dan menggunakan presisi desimal, maka itu benar-benar hanya masalah menggunakan eksponen 10 berdasarkan berapa banyak tempat desimal.
Nilai angka terdekat dengan presisi sama dengan angka. Jika nilainya setengah di antara dua angka, yang satu genap dan ganjil lainnya, maka angka genap dikembalikan. Jika ketepatan nilai kurang dari digit, maka nilai dikembalikan tidak berubah.
Perilaku metode ini mengikuti IEEE Standard 754, bagian 4. Pembulatan semacam ini kadang-kadang disebut pembulatan ke terdekat, atau pembulatan bankir. Jika angka nol, pembulatan semacam ini kadang-kadang disebut pembulatan ke nol.
Silverlight tidak mendukung opsi MidpointRounding. Berikut adalah metode ekstensi untuk Silverlight yang menambahkan enum MidpointRounding:
publicenumMidpointRounding{ToEven,AwayFromZero}publicstaticclassDecimalExtensions{publicstaticdecimalRound(thisdecimal d,MidpointRounding mode){return d.Round(0, mode);}/// <summary>/// Rounds using arithmetic (5 rounds up) symmetrical (up is away from zero) rounding/// </summary>/// <param name="d">A Decimal number to be rounded.</param>/// <param name="decimals">The number of significant fractional digits (precision) in the return value.</param>/// <returns>The number nearest d with precision equal to decimals. If d is halfway between two numbers, then the nearest whole number away from zero is returned.</returns>publicstaticdecimalRound(thisdecimal d,int decimals,MidpointRounding mode){if( mode ==MidpointRounding.ToEven){returndecimal.Round(d, decimals);}else{decimal factor =Convert.ToDecimal(Math.Pow(10, decimals));int sign =Math.Sign(d);returnDecimal.Truncate(d * factor +0.5m* sign)/ factor;}}}
>.5menghasilkan perilaku yang sama dengan Math.Round. Pertanyaannya adalah apa yang terjadi ketika bagian desimal tepat 0.5. Math.Round memungkinkan Anda menentukan jenis algoritme pembulatan yang Anda inginkan
Panagiotis Kanavos
-2
Ini jelek sekali, tapi selalu menghasilkan pembulatan aritmatika yang benar.
Mencoba dengan 1,905 dengan 2 desimal akan memberikan 1,91 seperti yang diharapkan tetapi Math.Round(1.905,2,MidpointRounding.AwayFromZero)memberi 1,90! Metode Math.Round benar-benar tidak konsisten dan tidak dapat digunakan untuk sebagian besar masalah dasar yang mungkin dihadapi programmer. Saya harus memeriksa apakah (int) 1.905 * decimalPowerOfTen = Math.Round(number * decimalPowerOfTen, 2)karena saya tidak ingin mengumpulkan apa yang harus dibulatkan.
Math.Round(2.5, 0, MidpointRounding.AwayFromZero);
1.005
tidak dapat direpresentasikan secara persis ganda. Itu mungkin1.00499...
. Jika Anda menggunakanDecimal
masalah ini akan hilang. Keberadaan Math.Round berlebihan yang mengambil sejumlah digit desimal pada dobel adalah pilihan desain IMO yang meragukan, karena jarang akan bekerja dengan cara yang bermakna.Jawaban:
Pertama, ini bukan bug C # - itu akan menjadi bug .NET. C # adalah bahasanya - tidak memutuskan bagaimana
Math.Round
diimplementasikan.Dan kedua, tidak - jika Anda membaca dokumen , Anda akan melihat bahwa pembulatan standar adalah "pembulatan ke genap" (pembulatan bankir):
Anda dapat menentukan bagaimana
Math.Round
seharusnya membulatkan titik tengah menggunakan kelebihan yang mengambilMidpointRounding
nilai. Ada satu kelebihan dengan yangMidpointRounding
terkait dengan masing-masing kelebihan yang tidak memilikinya:Round(Decimal)
/Round(Decimal, MidpointRounding)
Round(Double)
/Round(Double, MidpointRounding)
Round(Decimal, Int32)
/Round(Decimal, Int32, MidpointRounding)
Round(Double, Int32)
/Round(Double, Int32, MidpointRounding)
Apakah default ini dipilih dengan baik atau tidak adalah masalah yang berbeda. (
MidpointRounding
hanya diperkenalkan di .NET 2.0. Sebelum itu saya tidak yakin ada cara mudah untuk menerapkan perilaku yang diinginkan tanpa melakukannya sendiri.) Secara khusus, sejarah telah menunjukkan bahwa itu bukan perilaku yang diharapkan - dan dalam kebanyakan kasus itu adalah dosa utama dalam desain API. Saya bisa melihat mengapa Pembulatan Banker berguna ... tetapi masih mengejutkan banyak orang.Anda mungkin tertarik untuk melihat enum (
RoundingMode
) yang setara dengan Java terdekat yang menawarkan lebih banyak opsi. (Itu tidak hanya berurusan dengan titik tengah.)sumber
Itu disebut pembulatan ke genap (atau pembulatan bankir), yang merupakan strategi pembulatan yang valid untuk meminimalkan kesalahan dalam jumlah
(MidpointRounding.ToEven)
. Teorinya adalah bahwa, jika Anda selalu membulatkan angka 0,5 ke arah yang sama, kesalahan akan bertambah lebih cepat (round-to-even seharusnya meminimalkan itu) (a) .Ikuti tautan ini untuk deskripsi MSDN tentang:
Math.Floor
, yang membulatkan ke arah infinity negatif.Math.Ceiling
, yang dibulatkan ke arah infinity positif.Math.Truncate
, yang membulatkan ke atas atau ke bawah menuju nol.Math.Round
, yang membulatkan ke bilangan bulat terdekat atau jumlah tempat desimal yang ditentukan. Anda dapat menentukan perilaku jika persis sama antara dua kemungkinan, seperti pembulatan sehingga angka akhir genap ("Round(2.5,MidpointRounding.ToEven)
" menjadi 2) atau sehingga jauh dari nol ("Round(2.5,MidpointRounding.AwayFromZero)
" menjadi 3).Diagram dan tabel berikut dapat membantu:
Perhatikan bahwa
Round
jauh lebih kuat daripada yang terlihat, hanya karena dapat membulatkan ke tempat desimal tertentu. Semua yang lain membulatkan ke nol desimal selalu. Sebagai contoh:Dengan fungsi-fungsi lain, Anda harus menggunakan tipuan multiply / bagi untuk mendapatkan efek yang sama:
(a) Tentu saja, teori itu tergantung pada fakta bahwa data Anda memiliki penyebaran nilai yang merata di belahan genap (0,5, 2.5, 4.5, ...) dan setengah aneh (1,5, 3,5, ...).
Jika semua "nilai setengah" adalah genap (misalnya), kesalahan akan terakumulasi secepat jika Anda selalu dibulatkan ke atas.
sumber
e
centang (= 2.8) lebih baik dari pada2
centang?Dari MSDN, Math.Round (double a) mengembalikan:
... dan 2.5, berada di tengah-tengah antara 2 dan 3, dibulatkan ke angka genap (2). ini disebut Pembulatan Banker (atau round-to-even), dan merupakan standar pembulatan yang umum digunakan.
Artikel MSDN yang sama:
Anda dapat menentukan perilaku pembulatan yang berbeda dengan memanggil kelebihan Math.Round yang mengambil
MidpointRounding
mode.sumber
Anda harus memeriksa MSDN untuk
Math.Round
:Anda dapat menentukan perilaku
Math.Round
menggunakan kelebihan:sumber
Sifat pembulatan
Pertimbangkan tugas pembulatan bilangan yang berisi sebagian kecil, misalnya, bilangan bulat. Proses pembulatan dalam keadaan ini adalah untuk menentukan bilangan bulat mana yang paling tepat mewakili bilangan yang Anda bulatkan.
Secara umum, atau pembulatan 'aritmatika', jelas bahwa putaran 2.1, 2.2, 2.3 dan 2.4 menjadi 2.0; dan 2.6, 2.7, 2.8 dan 2.9 hingga 3.0.
Itu berarti 2.5, yang tidak lebih dekat ke 2.0 daripada ke 3.0. Terserah Anda untuk memilih antara 2.0 dan 3.0, keduanya akan sama-sama valid.
Untuk angka minus, -2.1, -2.2, -2.3 dan -2.4, akan menjadi -2.0; dan -2.6, 2.7, 2.8 dan 2.9 akan menjadi -3.0 di bawah pembulatan aritmatika.
Untuk -2.5 dibutuhkan pilihan antara -2.0 dan -3.0.
Bentuk pembulatan lainnya
'Pembulatan' mengambil angka apa pun dengan tempat desimal dan menjadikannya nomor 'keseluruhan' berikutnya. Dengan demikian, tidak hanya 2,5 dan 2,6 putaran ke 3,0, tetapi begitu juga 2,1 dan 2,2.
Pembulatan memindahkan angka positif dan negatif dari nol. Misalnya. 2,5 hingga 3,0 dan -2,5 hingga -3,0.
'Membulatkan ke bawah' memotong angka dengan memotong angka yang tidak diinginkan. Ini memiliki efek memindahkan angka ke nol. Misalnya. 2,5 hingga 2,0 dan -2,5 hingga -2,0
Dalam "pembulatan bankir" - dalam bentuknya yang paling umum - .5 yang akan dibulatkan dibulatkan ke atas atau ke bawah sehingga hasil pembulatan selalu berupa bilangan genap. Jadi 2,5 putaran ke 2.0, 3.5 ke 4.0, 4.5 ke 4.0, 5.5 ke 6.0, dan seterusnya.
'Alternate rounding' sebagai pengganti proses untuk 0,5 antara pembulatan ke bawah dan pembulatan ke atas.
'Pembulatan acak' melingkar .5 ke atas atau ke bawah secara acak.
Simetri dan asimetri
Fungsi pembulatan dikatakan 'simetris' jika ia membulatkan semua angka dari nol atau membulatkan semua angka ke nol.
Fungsi adalah 'asimetris' jika membulatkan angka positif ke nol dan angka negatif menjauh dari nol .. Misalnya. 2,5 hingga 2,0; dan -2,5 hingga -3,0.
Juga asimetris adalah fungsi yang membulatkan angka positif dari nol dan angka negatif ke nol. Misalnya. 2,5 hingga 3,0; dan -2,5 hingga -2,0.
Sebagian besar waktu orang berpikir tentang pembulatan simetris, di mana -2.5 akan dibulatkan ke -3.0 dan 3.5 akan dibulatkan ke 4.0. (dalam C #
Round(AwayFromZero)
)sumber
Defaultnya
MidpointRounding.ToEven
, atau pembulatan Bankir ( 2,5 menjadi 2, 4,5 menjadi 4 dan seterusnya ) telah menyengat saya sebelumnya dengan menulis laporan untuk akuntansi, jadi saya akan menulis beberapa kata dari apa yang saya temukan, sebelumnya dan dari melihat ke dalamnya untuk posting ini.Siapa saja bankir yang mengumpulkan angka genap (mungkin bankir Inggris!)?
Dari wikipedia
Tampaknya cara pembulatan yang sangat aneh terutama untuk perbankan, kecuali tentu saja bank menggunakan untuk menerima banyak simpanan dalam jumlah genap. Setor £ 2,4 juta, tapi kami akan menyebutnya £ 2 juta, pak.
Standar IEEE 754 tanggal kembali ke 1985 dan memberikan kedua cara pembulatan, tetapi dengan bankir sebagai yang direkomendasikan oleh standar. Ini artikel wikipedia memiliki daftar panjang tentang bagaimana bahasa menerapkan pembulatan (saya benar jika salah satu di bawah salah) dan yang paling tidak menggunakan Bankers' tetapi pembulatan Anda diajarkan di sekolah:
sumber
Dari MSDN:
http://msdn.microsoft.com/en-us/library/system.math.round.aspx
sumber
Karena Silverlight tidak mendukung opsi MidpointRounding, Anda harus menulis sendiri. Sesuatu seperti:
Untuk contoh termasuk cara menggunakan ini sebagai ekstensi lihat posting: .NET dan Silverlight Rounding
sumber
Saya punya masalah ini di mana server SQL saya mengumpulkan 0,5 hingga 1 sedangkan aplikasi C # saya tidak. Jadi, Anda akan melihat dua hasil yang berbeda.
Inilah implementasi dengan int / long. Ini adalah bagaimana putaran Jawa.
Ini mungkin metode yang paling efisien yang dapat Anda pikirkan juga.
Jika Anda ingin membuatnya ganda dan menggunakan presisi desimal, maka itu benar-benar hanya masalah menggunakan eksponen 10 berdasarkan berapa banyak tempat desimal.
Anda dapat memasukkan desimal negatif untuk titik desimal dan kata itu juga baik.
sumber
Cara sederhana adalah:
sumber
Posting ini memiliki jawaban yang Anda cari:
http://weblogs.asp.net/sfurman/archive/2003/03/07/3537.aspx
Pada dasarnya inilah yang dikatakan:
Nilai Pengembalian
Nilai angka terdekat dengan presisi sama dengan angka. Jika nilainya setengah di antara dua angka, yang satu genap dan ganjil lainnya, maka angka genap dikembalikan. Jika ketepatan nilai kurang dari digit, maka nilai dikembalikan tidak berubah.
Perilaku metode ini mengikuti IEEE Standard 754, bagian 4. Pembulatan semacam ini kadang-kadang disebut pembulatan ke terdekat, atau pembulatan bankir. Jika angka nol, pembulatan semacam ini kadang-kadang disebut pembulatan ke nol.
sumber
Silverlight tidak mendukung opsi MidpointRounding. Berikut adalah metode ekstensi untuk Silverlight yang menambahkan enum MidpointRounding:
Sumber: http://anderly.com/2009/08/08/silverlight-midpoint-rounding-solution/
sumber
menggunakan pembulatan khusus
sumber
>.5
menghasilkan perilaku yang sama denganMath.Round
. Pertanyaannya adalah apa yang terjadi ketika bagian desimal tepat0.5
. Math.Round memungkinkan Anda menentukan jenis algoritme pembulatan yang Anda inginkanIni jelek sekali, tapi selalu menghasilkan pembulatan aritmatika yang benar.
sumber
Math.Round
dan menentukan bagaimana Anda ingin membulatkannya.Inilah cara saya harus mengatasinya:
Mencoba dengan 1,905 dengan 2 desimal akan memberikan 1,91 seperti yang diharapkan tetapi
Math.Round(1.905,2,MidpointRounding.AwayFromZero)
memberi 1,90! Metode Math.Round benar-benar tidak konsisten dan tidak dapat digunakan untuk sebagian besar masalah dasar yang mungkin dihadapi programmer. Saya harus memeriksa apakah(int) 1.905 * decimalPowerOfTen = Math.Round(number * decimalPowerOfTen, 2)
karena saya tidak ingin mengumpulkan apa yang harus dibulatkan.sumber
Math.Round(1.905,2,MidpointRounding.AwayFromZero)
kembali1.91