2017-10-17 2 views
0

Wie in Frage, wie in C# mit n.5 Wert aufrunden (n ganze Zahl ist):Wie aufrunden (nicht Decke) in C#: n.5 bis zu (+) Unbegrenzte

1.5 -> 2 
2.5 -> 3 
-1.5 -> -1 
-2.5 -> -2 

1.4 -> 1 
1.6 -> 2 
-1.4 -> -1 
-1.6 -> -2 

I Suche aber in C#, Math.Round nur Unterstützung MidpointRounding.AwayFromZero und MidpointRounding.ToEven. Vielleicht sollte Programmierer Trick machen, um eine Zahl im normalen Leben zu runden (nicht Bankwesen oder akademischer Gedanke ...)?

Das Ergebnis erwartet wie in Javascript, Wert n.5 unendlich aufrunden zu (+) immer + ∞

+0

@AluanHaddad: Versuchen 'Math.Round (-3,5)'. (.NET wird standardmäßig abgerundet.) – Ryan

+0

@AluanHaddad In C# ist die Standardrunde ** ToEven **. Also '-2.5 -> -2' und' -1.5 -> -2' auch. Sie könnten es in http://rexttester.com/ –

+1

versuchen Verwandte [SO] (https://stackoverflow.com/questions/311696/why-does-net-use-bankers-rounding-as-default) und [Math .SE] (https://mathematica.stackexchange.com/questions/2116/why-round-to-even-integers). Round half-up ist nicht wirklich "normales Leben", es ist genau das, was normalerweise in der Grundschule gelehrt wird. – Martheen

Antwort

1

Try this :)

[TestFixture] 
public class TestClass 
{ 
    int NumberOfDecimalDigits(double d) 
    { 
     var text = Math.Abs(d).ToString(); 
     int integerPlaces = text.IndexOf('.'); 
     int decimalPlaces = text.Length - integerPlaces - 1; 
     return decimalPlaces; 
    } 

    double GetDelta(int numberOfDecimalDigits) 
    { 
     var deltaStringBuilder = new StringBuilder(); 
     deltaStringBuilder.Append("1"); 
     for (int i = 0; i < numberOfDecimalDigits; i++) 
     { 
      deltaStringBuilder.Append("0"); 
     } 


     double delta = 1/double.Parse(deltaStringBuilder.ToString()); 
     return delta; 
    } 

double Round(double value, int digits) 
     { 
      if (value > 0) 
      { 
       return Math.Round(value, digits, MidpointRounding.AwayFromZero); 
      } 
      if (value < 0) 
      { 
       var numberOfDecimalDigits = NumberOfDecimalDigits(value); 
       double delta = GetDelta(numberOfDecimalDigits); 
       return Math.Round(value + delta, digits, MidpointRounding.AwayFromZero); 
      } 

      return value; 
     } 

    double Round(double value) 
    { 
     if (value > 0) 
     { 
      return Math.Round(value, MidpointRounding.AwayFromZero); 
     } 
     if (value < 0) 
     { 
      var numberOfDecimalDigits = NumberOfDecimalDigits(value); 
      double delta = GetDelta(numberOfDecimalDigits); 
      return Math.Round(value + delta, MidpointRounding.AwayFromZero); 
     } 

     return value; 
    } 
    [Test] 
    public void TestMethod() 
    { 
     Assert.AreEqual(Round(1), 1); 
     Assert.AreEqual(Round(1.9), 2); 
     Assert.AreEqual(Round(1.5), 2); 
     Assert.AreEqual(Round(2.5), 3); 

     Assert.AreEqual(Round(-1), -1); 
     Assert.AreEqual(Round(-2.9), -3); 

     Assert.AreEqual(Round(-1.5), -1); 
     Assert.AreEqual(Round(-2.5), -2); 
     Assert.AreEqual(Round(1.4), 1); 
     Assert.AreEqual(Round(1.6), 2); 

     Assert.AreEqual(Round(-1.4), -1); 
     Assert.AreEqual(Round(-1.6), -2); 
     Assert.AreEqual(Round(-1.55), -2); 

     Assert.AreEqual(Round(-1.6666), -2); 
     Assert.AreEqual(Round(-0.9999999), -1); 
     Assert.AreEqual(Round(-0.001), 0); 

     Assert.AreEqual(Round(2.35, 1), 2.4); 
     Assert.AreEqual(Round(-2.35, 1), -2.3); 

    } 
+0

Diese Runden '-1.55' bis' -1'. – Ryan

+0

@Ryan Lassen Sie das Update überprüfen –

1

Hier ist eine Version, die alle übergibt Ihre Testfälle.

static void Main(string[] args) 
    { 
     Round(double.Epsilon, 0); 
     Round(0-double.Epsilon, 0); 

     Round(1 + double.Epsilon, 1); 
     Round(1 - double.Epsilon, 1); 


     Round(1.5, 2); 
     Round(2.5, 3); 
     Round(-1.5, -1); 
     Round(-2.5, -2); 

     Round(1.4, 1); 
     Round(1.6, 2); 
     Round(-1.4, -1); 
     Round(-1.6, -2); 
    } 

    private static void Round(double v1, int v2) 
    { 
     var equal = (MyRound(v1) == v2) ? "==" : "!="; 
     Console.WriteLine($"Math.Round({v1}) {equal} {v2}, it's {MyRound(v1)}"); 
    } 

    private static double MyRound(double v1) 
    { 
     return (v1 < 0) 
      ? 0 - Math.Round(Math.Abs(v1)-0.1) 
      : Math.Round(v1, MidpointRounding.AwayFromZero); 
    } 

Ausgang:

Math.Round(4.94065645841247E-324) == 0, it's 0 
Math.Round(-4.94065645841247E-324) == 0, it's 0 
Math.Round(1) == 1, it's 1 
Math.Round(1) == 1, it's 1 
Math.Round(1.5) == 2, it's 2 
Math.Round(2.5) == 3, it's 3 
Math.Round(-1.5) == -1, it's -1 
Math.Round(-2.5) == -2, it's -2 
Math.Round(1.4) == 1, it's 1 
Math.Round(1.6) == 2, it's 2 
Math.Round(-1.4) == -1, it's -1 
Math.Round(-1.6) == -2, it's -2 
+0

@Dan Nguyen gewinnt um 3 Minuten :) – mayu

+0

Warum 0!?!?! Math.Round (-4.94065645841247E-324) == 0, es ist 0 –

+1

Die Nummer ist -4.94E-324 - es ist eine sehr kleine Anzahl :) – mayu