Katakanlah saya memiliki nilai 3,4679 dan ingin 3,46, bagaimana saya dapat memotong ke dua tempat desimal tanpa pembulatan?
Saya telah mencoba yang berikut tetapi ketiganya memberi saya 3,47:
void Main()
{
Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
Console.Write(Math.Round(3.4679, 2));
}
Ini mengembalikan 3,46, tetapi sepertinya kotor entah bagaimana:
void Main()
{
Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
Akan lebih berguna jika memiliki fungsi lengkap untuk penggunaan dunia nyata memotong desimal dalam C #. Ini dapat diubah menjadi metode ekstensi Desimal dengan cukup mudah jika Anda ingin:
Jika Anda membutuhkan VB.NET coba ini:
Kemudian gunakan seperti ini:
atau
sumber
Gunakan operator modulus:
hasil: 0,54
sumber
0.5400
... Jawaban oleh D. Nesterov di bawah ini menghasilkan yang diharapkan0.54
.$"{0.54m:C}"
produksi"$0.54"
dan ya,$"{0.5400m:C}"
produksi"$0.54"
.Metode universal dan cepat (tanpa
Math.Pow()
/ perkalian) untukSystem.Decimal
:sumber
Satu masalah dengan contoh lainnya adalah mereka mengalikan nilai input sebelum membaginya. Ada kasus tepi di sini bahwa Anda dapat melimpah desimal dengan mengalikannya terlebih dahulu, kasus tepi, tetapi sesuatu yang saya temui. Lebih aman menangani bagian pecahan secara terpisah sebagai berikut:
sumber
Saya akan meninggalkan solusi untuk angka desimal.
Beberapa solusi untuk desimal di sini cenderung meluap (jika kita melewatkan angka desimal yang sangat besar dan metode akan mencoba mengalikannya).
Solusi Tim Lloyd dilindungi dari luapan tetapi tidak terlalu cepat.
Solusi berikut ini sekitar 2 kali lebih cepat dan tidak memiliki masalah overflow:
sumber
Truncate
metode Anda akan dikelompokkan bersama dengan yang asli .net, memberikan pengalaman yang mulus bagi pengguna.Assert.AreEqual(1.1m, 1.12m.TruncateEx(1));
gagal karena ini. Jika Anda menentukan pembulatan "normal" (AwayFromZero) dalam panggilan Math.Round, makaAssert.AreEqual(0m, 0m.TruncateEx(1));
gagalMidpointRounding.AwayFromZero
dan secara khusus kode untuk menangani nilai 0.Ini adalah pertanyaan lama, tetapi banyak pengguna tidak berkinerja baik atau berlebihan untuk jumlah besar. Saya pikir jawaban D. Nesterov adalah yang terbaik: kuat, sederhana dan cepat. Saya hanya ingin menambahkan dua sen saya. Saya bermain-main dengan desimal dan juga memeriksa kode sumbernya . Dari
public Decimal (int lo, int mid, int hi, bool isNegative, byte scale)
dokumentasi konstruktor .Mengetahui hal ini, pendekatan pertama saya adalah membuat yang lain
decimal
yang skalanya sesuai dengan desimal yang ingin saya buang, lalu potong dan akhirnya buat desimal dengan skala yang diinginkan.Metode ini tidak lebih cepat dari metode D. Nesterov dan lebih kompleks, jadi saya bermain-main sedikit lebih banyak. Dugaan saya adalah bahwa harus membuat auxiliar
decimal
dan mengambil bit dua kali membuatnya lebih lambat. Pada upaya kedua saya, saya memanipulasi komponen yang dikembalikan oleh metode Decimal.GetBits (Decimal d) sendiri. Idenya adalah membagi komponen dengan 10 kali sebanyak yang dibutuhkan dan mengurangi skala. Kode ini didasarkan (sangat) pada metode Decimal.InternalRoundFromZero (ref Decimal d, int decimalCount) .Saya belum melakukan tes kinerja yang ketat, tetapi pada MacOS Sierra 10.12.6, prosesor Intel Core i3 3,06 GHz dan menargetkan .NetCore 2.1 metode ini tampaknya jauh lebih cepat daripada D. Nesterov (saya tidak akan memberikan angka sejak , seperti yang telah saya sebutkan, pengujian saya tidak ketat). Terserah siapa pun yang menerapkan ini untuk mengevaluasi apakah kinerja yang diperoleh terbayar untuk kompleksitas kode yang ditambahkan.
sumber
apakah ini akan berhasil untukmu?
sumber
Akan
((long)(3.4679 * 100)) / 100.0
memberikan apa yang Anda inginkan?sumber
Berikut adalah metode ekstensi:
sumber
Jika Anda tidak terlalu khawatir tentang kinerja dan hasil akhir Anda bisa berupa string, pendekatan berikut akan tahan terhadap masalah presisi mengambang:
sumber
Berikut adalah implementasi fungsi TRUNC saya
sumber
bagaimana dengan ini?
sumber
Selain solusi di atas, ada cara lain yang bisa kami capai.
sumber
Dalam beberapa kondisi, ini mungkin cukup.
Saya memiliki nilai desimal SubCent = 0.0099999999999999999999999999M yang cenderung diformat ke | SubCent: 0.010000 | melalui
string.Format("{0:N6}", SubCent );
dan banyak pilihan pemformatan lainnya.Persyaratan saya bukanlah membulatkan nilai SubCent, tetapi juga tidak mencatat setiap digit.
Berikut ini memenuhi kebutuhan saya:
Yang mengembalikan string: | SubCent: 0.0099999 |
Untuk mengakomodasi nilai yang memiliki bagian integer, berikut ini adalah permulaan.
Yang mengembalikan string:
sumber
saya menggunakan fungsi ini untuk memotong nilai setelah desimal dalam variabel string
sumber
Inilah yang saya lakukan:
mengurangi dua angka yang dimasukkan tanpa membulatkan ke atas atau ke bawah desimal. karena solusi lain tidak berhasil untuk saya. tidak tahu apakah ini akan berhasil untuk orang lain, saya hanya ingin membagikan ini :) Semoga berhasil bagi mereka yang menemukan solusi untuk masalah yang mirip dengan saya. Terima kasih
PS: Saya seorang pemula jadi silakan tunjukkan sesuatu tentang ini. : D ini bagus jika Anda benar-benar berurusan dengan uang, penyebab sen kan? itu hanya memiliki 2 tempat desimal dan pembulatannya adalah tidak, tidak.
sumber
sumber
sumber
Sebenarnya Anda menginginkan 3,46 dari 3,4679. Ini hanya representasi karakter, jadi tidak ada hubungannya dengan fungsi matematika, fungsi matematika tidak dimaksudkan untuk melakukan pekerjaan ini. Cukup gunakan kode berikut.
sumber
bagaimana dengan
sumber