2011-01-27 21 views
5

Guys, Yuvarlama için bir yöntem yazıyorum. Girdi bir ondalık tiptir (dört ondalık basamak garantili). Yuvarlama kuralı, 0,005 veya daha azının göz ardı edilmesi, yani üçüncü ondalık haneye bakmasıdır - < = 5 ise, yuvarlama işlemi tamamlanır. Bazı kullanım durumları: 82.3657 -> 82.36, 82.3667 -> 82.37, 82.5967 -> 82.60, 82.9958 -> 82.99, 82.9968 -> 83.00 Herhangi bir iyi fikir? Ben şu şekilde çalıştım.Özel ondalık cinsinden yuvarlama C#

private decimal CustomRound(decimal x) 
{ 
    decimal rX = Math.Truncate(x * 100)/100; 
    decimal x3DecPlaces = Math.Truncate(x * 1000)/1000; 
    decimal t = (x3DecPlaces * 1000) % 10; 
    if (t >= 6) 
     rX = rX + 0.01m; 
    return rX; 
} 

cevap

7

Bunun için yerleşik bir şey olduğuna inanmıyorum, çünkü bu oldukça sıra dışı bir gereksinimdir (örneğin 1.3358'nin 1.33'e 1.33'ten daha yakın olduğu fikri tekildir). Kodunuz makul olarak uygun görünüyor.

DÜZENLEME: Eğer yuvarlama başlar noktadır orta noktası olmadığından, buradan istediğiniz etkiyi elde etmek MidpointRounding kullanamazsınız - bu 1,336 yerine normal 1.335 den (diyelim) var. Sadece 1.335, 1.33 ve 1.34 arasında orta nokta olarak kabul edilir, çünkü , orta nokta olan'dur. Olağandışı bir şekilde burada yanlı bir şekilde yuvarlanmış bir yeriniz var.

Üç DP'ye kesebiliyorsunuz ve MidpointRounding numaralı telefonu kullanamıyorsunuz, çünkü "sıfır doğru" modu yok.

biri biraz garip seçenek etkin bir önyargı kendiniz gerçekleştirmek olacaktır:

private static decimal CustomRound(decimal x) 
{ 
    return decimal.Round(x - 0.001m, 2, MidpointRounding.AwayFromZero); 
} 

yüzden 82.3647 olarak gördüğünü ve yuvarlak 82.36 ile 82.3657 davranacağını; 82.3667 ve 82.3657'yi tedavi eder ve 82.37'ye yuvarlar ve 82.5967'yi 82.5957 olarak tedavi eder ve 82.60'a yuvarlar. I 'u ne yaparsa yapar - ama sadece pozitif değerler için. Olumsuz değerler için tam olarak hangi davranışı istediğinizi öğrenmelisiniz.

Ne yaparsanız yapın, siz çok net belgelemek gerekir :)

Sadece tercih meselesi olarak, sadece her şey gerçekten ondalık ile yapıldığını daha anlaşılabilir olması için, Math.Truncate yerine decimal.Truncate kullanmak.

+0

@Downvoter: Yorum yapmak ister misiniz? –

+0

Evet, yerleşik yöntemleri kullanmaya çalışmakla uğraştım. Teşekkürler. – redzon

-1

Belki Math.Round (Double, Int32) yöntemini kullanabilirsiniz?

+4

ikiye ondalık dönüştürme ve sonra tekrar korkunç bir fikirdir - bu oldukça fazla anlamsız başlamak ondalık kullanmak demektir. –

+0

@Jon: Decimals ile çalışan bir Math.Round [aşırı yük] (http://msdn.microsoft.com/en-us/library/ms131275.aspx) var. – Vlad

+0

@Vlad: Elbette, ama bu cevap özellikle çift kullanarak aşırı yükü çağırıyor. –

0

Negatif değerleri nasıl ele almak istersiniz? -13,999'un -13,99'a değil -14'e kadar olmasını ister misiniz?

Bu durumda, +/- 0.01m, x'un negatif mi yoksa pozitif mi olduğuna bağlı olmalıdır.

Bu bunu yapmak için daha kolay bir yoludur:

decimal CustomRound(decimal x) 
{ 
    var offset = x >= 0 ? -0.001m : 0.001m; 
    return Decimal.Round(x + offset, 2, MidpointRounding.AwayFromZero); 
}