Wie runde ich den Wert C # auf die nächste ganze Zahl auf?


78

Ich möchte doppelt auf int aufrunden.

Z.B,

double a=0.4, b=0.5;

Ich möchte beide in eine Ganzzahl ändern.

damit

int aa=0, bb=1;

aaist von aund bbist vonb .

Irgendeine Formel, um das zu tun?


5
Was möchten Sie tun, wenn das Double außerhalb des Bereichs von int liegt?
Eric Lippert

Antworten:


204

Verwendung Math.Ceilingaufrunden

Math.Ceiling(0.5); // 1

Verwenden Sie, Math.Roundum nur zu runden

Math.Round(0.5, MidpointRounding.AwayFromZero); // 1

Und Math.Floorabzurunden

Math.Floor(0.5); // 0

Sie müssen mehr mit Math.Round arbeiten. Es bietet eine Aufzählung (MidpointRounding), um das Verhalten genau anzugeben.
Jnielsen

@jnielsen: Danke, dass du darauf hingewiesen hast und für das Codebeispiel. Ich habe es korrigiert.
BrunoLM

Der einfachste und effektivste Weg ist Math.Ceiling
yopez83

Bitte beachten Sie, dass Math.Ceilingdieselbe Nummer zurückgegeben wird, wenn die Nummer bereits vollständig ist. Sie wird NICHT um 1
Big Money


5

Das .NET Framework verwendet Math.Roundstandardmäßig die Rundung des Bankiers . Sie sollten diese Überladung verwenden:

Math.Round(0.5d, MidpointRounding.AwayFromZero)  //1
Math.Round(0.4d, MidpointRounding.AwayFromZero)  //0

3

Verwenden Sie eine Funktion anstelle von MidpointRounding.AwayFromZero:

myRound(1.11125,4)

Antwort: - 1.1114

public static Double myRound(Double Value, int places = 1000)
{
    Double myvalue = (Double)Value;
    if (places == 1000)
    {
        if (myvalue - (int)myvalue == 0.5)
        {
            myvalue = myvalue + 0.1;
            return (Double)Math.Round(myvalue);
        }
        return (Double)Math.Round(myvalue);
        places = myvalue.ToString().Substring(myvalue.ToString().IndexOf(".") + 1).Length - 1;
    } if ((myvalue * Math.Pow(10, places)) - (int)(myvalue * Math.Pow(10, places)) > 0.49)
    {
        myvalue = (myvalue * Math.Pow(10, places + 1)) + 1;
        myvalue = (myvalue / Math.Pow(10, places + 1));
    }
    return (Double)Math.Round(myvalue, places);
}

2
Dies schlägt fehl, wenn die aktuelle Kultur Kommas anstelle von Punkt für den Dezimalpunkt verwendet.
Sean Reid

3

Math.Round

Rundet einen Gleitkommawert mit doppelter Genauigkeit auf den nächsten Integralwert.


Allerdings: "Das Verhalten dieser Methode folgt dem IEEE-Standard 754, Abschnitt 4. Diese Art der Rundung wird manchmal als Rundung auf die nächste oder

0

Math.Round (0.5) gibt aufgrund von Gleitkomma-Rundungsfehlern Null zurück. Daher müssen Sie dem ursprünglichen Wert einen Rundungsfehler hinzufügen, um sicherzustellen, dass er nicht abgerundet wird, z.

Console.WriteLine(Math.Round(0.5, 0).ToString()); // outputs 0 (!!)
Console.WriteLine(Math.Round(1.5, 0).ToString()); // outputs 2
Console.WriteLine(Math.Round(0.5 + 0.00000001, 0).ToString()); // outputs 1
Console.WriteLine(Math.Round(1.5 + 0.00000001, 0).ToString()); // outputs 2
Console.ReadKey();

es ist mir egal ... das habe ich auch herausgefunden.
William

8
Es gibt keinen Fehler. 1/2 kann genau als Doppel dargestellt werden. Die Dokumente sagen: "Wenn die Bruchkomponente von a auf halbem Weg zwischen zwei ganzen Zahlen liegt, von denen eine gerade und die andere ungerade ist, wird die gerade Zahl zurückgegeben." 0 ist die gerade Zahl. Dieser Fudge-Faktor macht Zahlen wie 0,499999995 falsch.
Matthew Flaschen

Prost auf das Heads-up. Ich habe versucht sicherzustellen, dass das OP wusste, dass Round nicht so einfach funktioniert, wie andere es vorgeschlagen hatten. Zum Glück weiß das OP jetzt, dass es darauf achten muss, und ich habe ein besseres Verständnis für Round. =)
Will

0

Es ist auch möglich, negative ganze Zahlen zu runden

// performing d = c * 3/4 where d can be pos or neg
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
// explanation:
// 1.) multiply:          c * a  
// 2.) if c is negative:  (c>0? subtract half of the dividend 
//                              (b>>1) is bit shift right = (b/2)
//     if c is positive:  else  add half of the dividend 
// 3.) do the division
// on a C51/52 (8bit embedded) or similar like ATmega the below code may execute in approx 12cpu cycles (not tested)

Erweitert von einem Tipp irgendwo anders hier drin. Entschuldigung, von wo aus verpasst.

/* Example test: integer rounding example including negative*/
#include <stdio.h>
#include <string.h>

int main () {
   //rounding negative int
   // doing something like d = c * 3/4
   int a=3;
   int b=4;
   int c=-5;
   int d;
   int s=c;
   int e=c+10;


   for(int f=s; f<=e; f++) {
      printf("%d\t",f);

      double cd=f, ad=a, bd=b , dd;

      // d = c * 3/4  with double
      dd = cd * ad / bd;

      printf("%.2f\t",dd);
      printf("%.1f\t",dd);        
      printf("%.0f\t",dd);

      // try again with typecast have used that a lot in Borland C++ 35 years ago....... maybe evolution has overtaken it ;) ***
      // doing div before mul on purpose
      dd =(double)c * ((double)a / (double)b);
      printf("%.2f\t",dd);

      c=f;
      // d = c * 3/4  with integer rounding
      d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
      printf("%d\t",d);
      puts("");
  }
 return 0;
}

/* test output
in  2f     1f   0f cast int   
-5  -3.75   -3.8    -4  -3.75   -4  
-4  -3.00   -3.0    -3  -3.75   -3  
-3  -2.25   -2.2    -2  -3.00   -2  
-2  -1.50   -1.5    -2  -2.25   -2  
-1  -0.75   -0.8    -1  -1.50   -1  
 0   0.00    0.0     0  -0.75    0  
 1   0.75    0.8     1   0.00    1  
 2   1.50    1.5     2   0.75    2  
 3   2.25    2.2     2   1.50    2  
 4   3.00    3.0     3   2.25  3    
 5   3.75    3.8     4   3.00   

// by the way evolution: 
// Is there any decent small integer library out there for that by now?

-2

Es ist einfach. Folgen Sie also diesem Code.

decimal d = 10.5;
int roundNumber = (int)Math.Floor(d + 0.5);

Ergebnis ist 11


Warum verwenden, Math.Floorwenn das OP auf den nächsten runden möchte? Dies wird nicht für negative Werte
funktionieren

Dieses Beispiel nur für positive Werte.
TechnicalKalsa

Sie haben das in Ihrer Frage nicht einmal erwähnt. Und das OP hat nicht gesagt, dass er nur an positiven ganzen Zahlen interessiert ist. Auf jeden
Fall

-2

Andere Option:

string strVal = "32.11"; // will return 33
// string strVal = "32.00" // returns 32
// string strVal = "32.98" // returns 33

string[] valStr = strVal.Split('.');

int32 leftSide = Convert.ToInt32(valStr[0]);
int32 rightSide = Convert.ToInt32(valStr[1]);

if (rightSide > 0)
    leftSide = leftSide + 1;


return (leftSide);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.