Yuvarlamadan iki ondalık basamağı kes


109

Diyelim ki 3.4679 değerim var ve 3.46 istiyorum, yuvarlamadan iki ondalık basamağa nasıl kısaltabilirim?

Aşağıdakileri denedim ama üçü de bana 3.47 verdi:

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

Bu 3.46'yı döndürür, ancak bazı durumlarda kirli görünüyor:

void Main()
{
    Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
c#  math  rounding 

Yanıtlar:


153
value = Math.Truncate(100 * value) / 100;

Bunun gibi kesirlerin kayan noktada doğru şekilde temsil edilemeyeceğine dikkat edin.


13
Değerleriniz için ondalık kullanın ve bu cevap işe yarayacaktır. Her zaman herhangi bir kayan noktalı gösterimde çalışmak pek olası değildir.
driis

1
Bu, kayan nokta değişmez değerlerinde yuvarlama yönünü belirtmenin mümkün olup olmadığını merak etmeme neden oluyor. Hmmmm.
Steve314

Olmalı bazı bir sayı fazla 308 basamak saklayabilirsiniz varsayımıyla hesaplama olduğunu programcı anlatmak için bir yol fena halde uygunsuz. Double sadece 15 depolayabilir. Taşma burada çok fazla bir özellik, oldukça kötü bir şekilde taştı.
Hans Passant

Üzgünüm, "değer" in ondalık olduğunu sanıyordum.
nightcoder

54

C # 'da bir ondalık basamağı kısaltmanın gerçek dünya kullanımı için tam bir işleve sahip olmak daha yararlı olacaktır. İsterseniz, bu oldukça kolay bir Decimal uzatma yöntemine dönüştürülebilir:

public decimal TruncateDecimal(decimal value, int precision)
{
    decimal step = (decimal)Math.Pow(10, precision);
    decimal tmp = Math.Truncate(step * value);
    return tmp / step;
}

VB.NET'e ihtiyacınız varsa şunu deneyin:

Function TruncateDecimal(value As Decimal, precision As Integer) As Decimal
    Dim stepper As Decimal = Math.Pow(10, precision)
    Dim tmp As Decimal = Math.Truncate(stepper * value)
    Return tmp / stepper
End Function

Öyleyse şu şekilde kullanın:

decimal result = TruncateDecimal(0.275, 2);

veya

Dim result As Decimal = TruncateDecimal(0.275, 2)

1
Bu, büyük sayılarda aşacak.
nightcoder

1
Night coder'a eklemek için, Int32'yi işlevinizde aracı olarak kullanıyor olmanız, taşmalara neden olacaktır. Gerçekten bir Tamsayıya çevirmeniz gerekiyorsa Int64 kullanmalısınız. Buradaki soru, Truncate yine de Decimal integralleri döndürdüğü için neden bu fazladan ek yüke maruz kalmak isteyeceğiniz olacaktır. Şöyle bir şey yapın: ondalık adım = (ondalık) Math.Pow (10, duyarlık); dönüş Math.Truncate (adım * değer) / adım;
Sarel Esterhuizen

Oyuncu kadrosunu Integer'a düşürdüm. Daha iyi okunabilirlik ve işlevin nasıl çalıştığını anlamak için onlara ayrı satırlar bıraktım.
Corgalore

27

Modül işlecini kullanın:

var fourPlaces = 0.5485M;
var twoPlaces = fourPlaces - (fourPlaces % 0.01M);

sonuç: 0,54


1
Anlamıyorum (okuyun: doğrulamak için zaman harcamadım), tüm bu diğer süslü çözümleri, bu tam olarak aradığımı yapıyor. Teşekkür ederim!
Isaac Baker

.Net Fiddle bu Running Clicky üretir 0.5400... D. Nesterov'un tarafından cevap aşağıda beklenen üretilen 0.54.
ttugates

@Ttugates, 0.54 ve 0.5400'ün tam olarak aynı değer olduğunu biliyorsunuz, değil mi? Görüntü için biçimlendirme zamanı gelmedikçe / gelene kadar kaç sıfırın ardından geldiği önemli değildir - bu durumda, doğru biçimlendirildiğinde sonuç aynı olacaktır: $"{0.54m:C}"üretir "$0.54"ve evet, $"{0.5400m:C}"üretir "$0.54".
Leonard Lewis

26

Aşağıdakiler için evrensel ve hızlı yöntem (çarpmadan Math.Pow()/ çarpmadan ) System.Decimal:

decimal Truncate(decimal d, byte decimals)
{
    decimal r = Math.Round(d, decimals);

    if (d > 0 && r > d)
    {
        return r - new decimal(1, 0, 0, false, decimals);
    }
    else if (d < 0 && r < d)
    {
        return r + new decimal(1, 0, 0, false, decimals);
    }

    return r;
}

4
Bunu diğer cevaplarda bahsedilen tüm testlerden geçirdim ve mükemmel çalışıyor. Daha fazla oy almaması şaşırttı. Ondalık sayıların yalnızca 0 ile 28 arasında olabileceğini belirtmekte fayda var (Muhtemelen çoğu insan için uygundur).
RichardOD

1
Ben ikinci oldum. Bu en iyi cevap. +1
Branko Dimitrijevic

1
Harika cevap, ben buna "kutunun dışında düşünmek"
diyorum

23

Diğer örneklerle ilgili bir sorun, girdi değerini bölmeden önce çarpmalarıdır . Burada, önce çarparak ondalık sayıları aşabileceğiniz bir uç durum var, bir uç durum, ama karşılaştığım bir şey. Kesirli kısmı ayrı ayrı şu şekilde ele almak daha güvenlidir:

    public static decimal TruncateDecimal(this decimal value, int decimalPlaces)
    {
        decimal integralValue = Math.Truncate(value);

        decimal fraction = value - integralValue;

        decimal factor = (decimal)Math.Pow(10, decimalPlaces);

        decimal truncatedFraction = Math.Truncate(fraction * factor) / factor;

        decimal result = integralValue + truncatedFraction;

        return result;
    }

Bunun eski olduğunu biliyorum ama bunun farkına vardım ve sorunum var. Burada sahip olduğunuz faktör bir int'dir ve bu nedenle, çok sayıda ondalık basamağa (25 diyelim) kısaltıyorsanız, sonuçta kesinlik hatası oluşmasına neden olur. Faktör türünü ondalık olarak değiştirerek düzelttim.
TheKingDave

@TheKingDave: Muhtemelen ilgisizdir, ancak faktör ondalıklara sahip olamayacağından, onu uzun süre modellemek daha iyi olmalı?
Ignacio Soler Garcia

@SoMoS Benim için Decimal daha iyi çalıştı çünkü bana faktör için en yüksek depolama değerlerini verdi. Hala bir sınırlaması var ama başvurum için yeterince büyük. Öte yandan Long, uygulamam için yeterince büyük sayıları saklayamadı. Örneğin, uzun ile Kes (25) yaparsanız, bazı yanlışlıklar olacaktır.
TheKingDave

@TheKingDave önerisine göre daha fazla yerde kesmeye izin verecek şekilde güncellendi, teşekkürler.
Tim Lloyd

6

Çözümü ondalık sayılar için bırakacağım.

Buradaki ondalık sayılar için çözümlerden bazıları taşmaya eğilimlidir (eğer çok büyük bir ondalık sayı geçersek ve yöntem onu ​​çarpmaya çalışır).

Tim Lloyd'un çözümü taşmaya karşı korumalı ancak çok hızlı değil.

Aşağıdaki çözüm yaklaşık 2 kat daha hızlıdır ve bir taşma sorunu yoktur:

public static class DecimalExtensions
{
    public static decimal TruncateEx(this decimal value, int decimalPlaces)
    {
        if (decimalPlaces < 0)
            throw new ArgumentException("decimalPlaces must be greater than or equal to 0.");

        var modifier = Convert.ToDecimal(0.5 / Math.Pow(10, decimalPlaces));
        return Math.Round(value >= 0 ? value - modifier : value + modifier, decimalPlaces);
    }
}

[Test]
public void FastDecimalTruncateTest()
{
    Assert.AreEqual(-1.12m, -1.129m. TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.120m. TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.125m. TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.1255m.TruncateEx(2));
    Assert.AreEqual(-1.12m, -1.1254m.TruncateEx(2));
    Assert.AreEqual(0m,      0.0001m.TruncateEx(3));
    Assert.AreEqual(0m,     -0.0001m.TruncateEx(3));
    Assert.AreEqual(0m,     -0.0000m.TruncateEx(3));
    Assert.AreEqual(0m,      0.0000m.TruncateEx(3));
    Assert.AreEqual(1.1m,    1.12m.  TruncateEx(1));
    Assert.AreEqual(1.1m,    1.15m.  TruncateEx(1));
    Assert.AreEqual(1.1m,    1.19m.  TruncateEx(1));
    Assert.AreEqual(1.1m,    1.111m. TruncateEx(1));
    Assert.AreEqual(1.1m,    1.199m. TruncateEx(1));
    Assert.AreEqual(1.2m,    1.2m.   TruncateEx(1));
    Assert.AreEqual(0.1m,    0.14m.  TruncateEx(1));
    Assert.AreEqual(0,      -0.05m.  TruncateEx(1));
    Assert.AreEqual(0,      -0.049m. TruncateEx(1));
    Assert.AreEqual(0,      -0.051m. TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.14m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.15m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.16m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.19m.  TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.199m. TruncateEx(1));
    Assert.AreEqual(-0.1m,  -0.101m. TruncateEx(1));
    Assert.AreEqual(0m,     -0.099m. TruncateEx(1));
    Assert.AreEqual(0m,     -0.001m. TruncateEx(1));
    Assert.AreEqual(1m,      1.99m.  TruncateEx(0));
    Assert.AreEqual(1m,      1.01m.  TruncateEx(0));
    Assert.AreEqual(-1m,    -1.99m.  TruncateEx(0));
    Assert.AreEqual(-1m,    -1.01m.  TruncateEx(0));
}

2
"Ex" ekini sevmiyorum. C # aşırı yüklemeyi destekler, Truncateyönteminiz .net yerel olanlarla birlikte gruplanarak kullanıcıya sorunsuz bir deneyim sunar.
Gqqnbig

1
Algoritmanız bazı yanlış sonuçlara neden oluyor. Varsayılan MidpointRounding modu, 0,5'i en yakın çift değere yuvarlayan Banker's Rounding'dir. Assert.AreEqual(1.1m, 1.12m.TruncateEx(1));bu nedenle başarısız olur. Math.Round çağrısında "normal" yuvarlamayı (AwayFromZero) belirtirseniz, Assert.AreEqual(0m, 0m.TruncateEx(1));başarısız olur
Jon Senchyna

1
Bu çözümün işe yaramasının tek yolu MidpointRounding.AwayFromZero, 0 değerini işlemek için kullanmanız ve özellikle kodlamanızdır.
Jon Senchyna

1
Jon haklı: 0m.TruncateEx (0), 0 açıkça işlenmediği sürece -1 ile sonuçlanır. Aynı şekilde -11m.TruncateEx (0), Math.Round içinde MidpointRounding.AwayFromZero kullanılmadığı sürece -10 sonucunu verir. Yine de bu değişikliklerle iyi çalışıyor gibi görünüyor.
Ho Ho Ho

1
AwayFromZero için yapılan değişiklikler ve 0, -9999999999999999999999999999m.TruncateEx (0) 'ın açıkça işlenmesiyle bile -9999999999999999999999999998 ile sonuçlanır, bu nedenle bazı durumlarda hala hatalı olabilir.
Ho Ho Ho

3

Bu eski bir sorudur, ancak çoğu cevap iyi performans göstermez veya büyük sayılar için taşmaz. Bence D. Nesterov cevabı en iyisi: sağlam, basit ve hızlı. Sadece iki sentimi eklemek istiyorum. Ondalık sayılarla oynadım ve kaynak kodunu da kontrol ettim . Gönderen public Decimal (int lo, int mid, int hi, bool isNegative, byte scale) yapıcı belgelerinde .

Bir Ondalık sayının ikili gösterimi 1 bitlik bir işaret, 96 bitlik bir tam sayı ve tamsayı sayısını bölmek ve bunun hangi kısmının ondalık kesir olduğunu belirtmek için kullanılan bir ölçekleme faktöründen oluşur. Ölçekleme faktörü örtük olarak 0 ile 28 arasında bir üsse yükseltilen 10 sayısıdır.

Bunu bilerek, ilk yaklaşımım decimalölçeği atmak istediğim ondalık sayıya karşılık gelen başka bir tane yaratmak , sonra onu kesmek ve sonunda istenen ölçekte bir ondalık oluşturmaktı.

private const int ScaleMask = 0x00FF0000;
    public static Decimal Truncate(decimal target, byte decimalPlaces)
    {
        var bits = Decimal.GetBits(target);
        var scale = (byte)((bits[3] & (ScaleMask)) >> 16);

        if (scale <= decimalPlaces)
            return target;

        var temporalDecimal = new Decimal(bits[0], bits[1], bits[2], target < 0, (byte)(scale - decimalPlaces));
        temporalDecimal = Math.Truncate(temporalDecimal);

        bits = Decimal.GetBits(temporalDecimal);
        return new Decimal(bits[0], bits[1], bits[2], target < 0, decimalPlaces);
    }

Bu yöntem D. Nesterov'unkinden daha hızlı değil ve daha karmaşık, bu yüzden biraz daha fazla oynadım. Tahminim, bir yardımcı oluşturmak decimalve bitleri iki kez almak zorunda kalmanın onu daha yavaş hale getirdiği. İkinci denememde Decimal.GetBits (Decimal d) yöntemiyle döndürülen bileşenleri kendim değiştirdim. Buradaki fikir, bileşenleri gerektiği kadar 10'a bölmek ve ölçeği küçültmektir. Kod, (büyük ölçüde) Decimal.InternalRoundFromZero (ref Decimal d, int decimalCount) yöntemine dayanır .

private const Int32 MaxInt32Scale = 9;
private const int ScaleMask = 0x00FF0000;
    private const int SignMask = unchecked((int)0x80000000);
    // Fast access for 10^n where n is 0-9        
    private static UInt32[] Powers10 = new UInt32[] {
        1,
        10,
        100,
        1000,
        10000,
        100000,
        1000000,
        10000000,
        100000000,
        1000000000
    };

    public static Decimal Truncate(decimal target, byte decimalPlaces)
    {
        var bits = Decimal.GetBits(target);
        int lo = bits[0];
        int mid = bits[1];
        int hi = bits[2];
        int flags = bits[3];

        var scale = (byte)((flags & (ScaleMask)) >> 16);
        int scaleDifference = scale - decimalPlaces;
        if (scaleDifference <= 0)
            return target;

        // Divide the value by 10^scaleDifference
        UInt32 lastDivisor;
        do
        {
            Int32 diffChunk = (scaleDifference > MaxInt32Scale) ? MaxInt32Scale : scaleDifference;
            lastDivisor = Powers10[diffChunk];
            InternalDivRemUInt32(ref lo, ref mid, ref hi, lastDivisor);
            scaleDifference -= diffChunk;
        } while (scaleDifference > 0);


        return new Decimal(lo, mid, hi, (flags & SignMask)!=0, decimalPlaces);
    }
    private static UInt32 InternalDivRemUInt32(ref int lo, ref int mid, ref int hi, UInt32 divisor)
    {
        UInt32 remainder = 0;
        UInt64 n;
        if (hi != 0)
        {
            n = ((UInt32)hi);
            hi = (Int32)((UInt32)(n / divisor));
            remainder = (UInt32)(n % divisor);
        }
        if (mid != 0 || remainder != 0)
        {
            n = ((UInt64)remainder << 32) | (UInt32)mid;
            mid = (Int32)((UInt32)(n / divisor));
            remainder = (UInt32)(n % divisor);
        }
        if (lo != 0 || remainder != 0)
        {
            n = ((UInt64)remainder << 32) | (UInt32)lo;
            lo = (Int32)((UInt32)(n / divisor));
            remainder = (UInt32)(n % divisor);
        }
        return remainder;
    }

Sıkı performans testleri yapmadım, ancak bir MacOS Sierra 10.12.6, 3.06 GHz Intel Core i3 işlemcide ve .NetCore 2.1'i hedefleyen bu yöntem, D.Nesterov'unkinden çok daha hızlı görünüyor. , bahsettiğim gibi, testlerim titiz değil). Performans kazanımlarının eklenen kod karmaşıklığı için işe yarayıp yaramadığını değerlendirmek, bunu uygulayan kişiye bağlıdır.


Tüm düşünce ve çabadan dolayı oy vermek zorunda kaldım. Nesterov'ları bir kriter olarak belirlediniz ve devam ettiniz - şapkalar kapalı.
AndrewBenjamin

2

bu senin için çalışır mı

Console.Write(((int)(3.4679999999*100))/100.0);

2

Misiniz ((long)(3.4679 * 100)) / 100.0istediğini vermek?


1

İşte bir uzatma yöntemi:

public static decimal? TruncateDecimalPlaces(this decimal? value, int places)
    {
        if (value == null)
        {
            return null;
        }

        return Math.Floor((decimal)value * (decimal)Math.Pow(10, places)) / (decimal)Math.Pow(10, places);

    } // end

0

Performans hakkında çok fazla endişelenmezseniz ve sonucunuz bir dizi olabilirse, aşağıdaki yaklaşım kayan hassasiyet sorunlarına karşı dayanıklı olacaktır:

string Truncate(double value, int precision)
{
    if (precision < 0)
    {
        throw new ArgumentOutOfRangeException("Precision cannot be less than zero");
    }

    string result = value.ToString();

    int dot = result.IndexOf('.');
    if (dot < 0)
    {
        return result;
    }

    int newLength = dot + precision + 1;

    if (newLength == dot + 1)
    {
        newLength--;
    }

    if (newLength > result.Length)
    {
        newLength = result.Length;
    }

    return result.Substring(0, newLength);
}

6
Aslında, kodlama '.' iyi bir fikir değil, System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator [0]
David Airapetyan

0

İşte TRUNC işlevi uygulamam

private static object Tranc(List<Expression.Expression> p)
{
    var target = (decimal)p[0].Evaluate();

    // check if formula contains only one argument
    var digits = p.Count > 1
        ? (decimal) p[1].Evaluate()
        : 0;

    return Math.Truncate((double)target * Math.Pow(10, (int)digits)) / Math.Pow(10, (int)digits);
}

0

Peki buna ne dersin?

Function TruncateDecimal2(MyValue As Decimal) As Decimal
        Try
            Return Math.Truncate(100 * MyValue) / 100
        Catch ex As Exception
            Return Math.Round(MyValue, 2)
        End Try
End Function

0

Yukarıdaki çözümlerin dışında, başarabileceğimiz başka bir yol var.

    decimal val=23.5678m,finalValue;

    //take the decimal part    
     int decimalPos = val.ToString().IndexOf('.');
     string decimalPart = val.ToString().Substring(decimalPosition+1,val.ToString().Length);
    //will result.56
   string wholePart=val.ToString().Substring(0,decimalPos-1);
   //concantinate and parse for decimal.
  string truncatedValue=wholePart+decimalPart;//"23.56"
  bool isDecimal=Decimal.tryParse(truncatedValue,out finalValue);//finalValue=23.56

0

Bazı koşullar altında bu yeterli olabilir.

| SubCent: 0.010000 | şeklinde biçimlendirme eğiliminde olan SubCent = 0.00999999999999999999999999M ondalık değerim vardı üzerindenstring.Format("{0:N6}", SubCent ); ve diğer birçok biçimlendirme seçeneği.

Benim ihtiyacım SubCent değerini yuvarlamak değil, her basamağı da günlüğe kaydetmekti.

Aşağıdakiler ihtiyacımı karşıladı:

string.Format("SubCent:{0}|", 
    SubCent.ToString("N10", CultureInfo.InvariantCulture).Substring(0, 9));

Bu dizeyi döndürür: | SubCent: 0.0099999 |

Bir tamsayı kısmına sahip değeri barındırmak için aşağıdaki bir başlangıçtır.

tmpValFmt = 567890.0099999933999229999999M.ToString("0.0000000000000000000000000000");
decPt = tmpValFmt.LastIndexOf(".");
if (decPt < 0) decPt = 0;
valFmt4 = string.Format("{0}", tmpValFmt.Substring(0, decPt + 9));

Hangi dizeyi döndürür:

valFmt4 = "567890.00999999"

0

Bu işlevi, bir dize değişkeninde ondalık sayıdan sonraki değeri kesmek için kullanıyorum

public static string TruncateFunction(string value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        else
        {
            string[] split = value.Split('.');
            if (split.Length > 0)
            {
                string predecimal = split[0];
                string postdecimal = split[1];
                postdecimal = postdecimal.Length > 6 ? postdecimal.Substring(0, 6) : postdecimal;
                return predecimal + "." + postdecimal;

            }
            else return value;
        }
    }

1
Bu kod soruyu yanıtlayabilirken, sorunun nasıl ve / veya neden çözüldüğüne ilişkin ek bağlam sağlamak, yanıtlayanın uzun vadeli değerini artıracaktır.
Nic3500

0

Yaptığım şey bu:

        c1 = a1 - b1;
        d1 = Math.Ceiling(c1 * 100) / 100;

girilen iki sayıyı ondalık sayıları yukarı veya aşağı yuvarlamadan çıkarma. çünkü diğer çözümler benim için çalışmıyor. başkaları için işe yarayıp yaramayacağını bilmiyorum, sadece bunu paylaşmak istiyorum :) Umarım benimkine benzer bir soruna çözüm arayanlar için işe yarar. Teşekkürler

Not: Ben bir acemiyim, bu yüzden bu konuda bir şeyler belirtmekten çekinmeyin. : D gerçekten parayla uğraşıyorsanız, bu iyi, çünkü sentler değil mi? sadece 2 ondalık basamağa sahiptir ve yuvarlama hayırdır.


0
        public static void ReminderDigints(decimal? number, out decimal? Value,  out decimal? Reminder)
        {
            Reminder = null;
            Value = null;
            if (number.HasValue)
            {
                Value = Math.Floor(number.Value);
                Reminder = (number - Math.Truncate(number.Value));
            }
        }



        decimal? number= 50.55m;             
        ReminderDigints(number, out decimal? Value, out decimal? Reminder);

0
public static decimal TruncateDecimalPlaces(this decimal value, int precision)
    {
        try
        {
            step = (decimal)Math.Pow(10, precision);
            decimal tmp = Math.Truncate(step * value);
            return tmp / step;
        }
        catch (OverflowException)
        {
            step = (decimal)Math.Pow(10, -1 * precision);
            return value - (value % step);
        }
    }

-2

Aslında 3.4679'dan 3.46'yı istiyorsunuz. Bu sadece karakterlerin temsilidir.Dolayısıyla matematik fonksiyonuyla ilgisi yoktur.Math fonksiyonunun bu işi yapması amaçlanmamıştır. Aşağıdaki kodu kullanmanız yeterlidir.

Dim str1 As String
str1=""
str1 ="3.4679" 
  Dim substring As String = str1.Substring(0, 3)

    ' Write the results to the screen.
    Console.WriteLine("Substring: {0}", substring)

Or 
    Please use the following code.
Public function result(ByVal x1 As Double) As String 
  Dim i as  Int32
  i=0
  Dim y as String
  y = ""
  For Each ch as Char In x1.ToString
    If i>3 then
     Exit For
    Else
    y + y +ch
    End if
    i=i+1
  Next
  return y
End Function

Yukarıdaki kod herhangi bir sayı için değiştirilebilir Aşağıdaki kodu bir düğme tıklama olayına yerleştirin

Dim str As String 
str= result(3.4679)
 MsgBox("The number is " & str)

-2

ne dersin

var i = Math.Truncate(number);var r = i + Math.Truncate((number - i) * 100) / 100;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.