Як округлити значення C # до найближчого цілого числа?


79

Я хочу округлити вдвічі більше до int.

Наприклад,

double a=0.4, b=0.5;

Я хочу змінити їх обох на цілі числа.

так що

int aa=0, bb=1;

aaє від aі bbє від b.

Будь-яка формула для цього?


5
Що ви хочете, якщо дубль знаходиться поза діапазоном int?
Eric Lippert,

Відповіді:


208

Використовуйте Math.Ceilingдля округлення

Math.Ceiling(0.5); // 1

Використовуйте Math.Roundпросто для округлення

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

І Math.Floorокругляти вниз

Math.Floor(0.5); // 0

Вам потрібно більше працювати з Math.Round. Він забезпечує перелік (MidpointRounding) для точного вказівки поведінки.
jnielsen

@jnielsen: Дякую, що вказали на це та за приклад коду. Я це виправив.
BrunoLM

Найпростішим та ефективним способом є Math.Ceiling
yopez83

Зверніть увагу, що Math.Ceilingповерне той самий номер, якщо число вже ціле, воно НЕ буде округлятися до 1
Великі гроші


6

.NET framework використовує округлення банкіра Math.Roundза замовчуванням. Ви повинні використовувати це перевантаження:

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

3

Використовуйте функцію замість MidpointRounding.AwayFromZero:

myRound(1.11125,4)

Відповідь: - 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
Це не вдасться, якщо поточна культура використовує коми, а не крапки для десяткової коми.
Шон Рід,

3

Математика. Раунд

Округлює значення з плаваючою комою з подвійною точністю до найближчого інтегрального значення.


Однак: "Поведінка цього методу відповідає стандарту IEEE 754, розділ 4. Цей тип округлення іноді називають округленням до найближчого або округленням банкіра ..."

0

Math.Round (0.5) повертає нуль через помилки округлення з плаваючою комою, тому вам потрібно додати суму помилки округлення до вихідного значення, щоб переконатися, що воно не округляється вниз, наприклад.

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

для мене це не має значення .. я також це дізнався.
Вільям

8
Помилки немає. 1/2 можна представити точно як подвійний. У документації сказано: "Якщо дробовий компонент a знаходиться на півдорозі між двома цілими числами, одне з яких парне, а друге непарне, тоді парне число повертається". 0 - парне число. Цей коефіцієнт обману зробить такі цифри, як 0,499999995, навколо неправильними.
Matthew Flaschen,

Вітаємо за хедз-ап. Я намагався переконатися, що ОП знає, що Раунд працює не так просто, як пропонували інші. На щастя, ОП тепер знає, що слід стежити за цим, і я краще розумію самого Круглого. =)
Буде

0

Також можна округлити від’ємні цілі числа

// 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)

Розширено з підказки десь ще тут. Вибачте, пропустив звідки.

/* 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

Це просто. Тож дотримуйтесь цього коду.

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

Результат - 11


навіщо використовувати, Math.Floorколи ОП хоче округлити до найближчого? Це не спрацює для негативних значень
phuclv

Цей приклад лише для позитивних значень.
TechnicalKalsa

ви навіть не згадали про це у своєму питанні. І ОП не сказав, що його цікавлять лише позитивні цілі числа. У будь-якому випадку це марно, бо вже є Math.Round
phuclv

-2

Інший варіант:

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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.