Як я можу перетворити подвійний на найближче ціле значення?


Відповіді:


78

Використовувати Math.round(), можливо, спільно зMidpointRounding.AwayFromZero

наприклад:

Math.Round(1.2) ==> 1
Math.Round(1.5) ==> 2
Math.Round(2.5) ==> 2
Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3

6
Не вдасться Convert.ToInt32()зробити те ж саме, чи він просто зніме все після десяткової?
Людина-булочка

208
Насправді не утворюється ціле число, а подвійне.
gatopeich

13
@Ronnie - ні, це за дизайном. За замовчуванням Math.Round округлятиме середні точки (x + .5) до найближчого парного числа. Якщо ви хочете іншої поведінки, вам потрібно вказати її через прапор. msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
nickf

6
Ну я ніколи! :)
Ронні

5
Подвійний не є Int.
Євгеній Набоков

267
double d = 1.234;
int i = Convert.ToInt32(d);

Довідково

Обробляє округлення так:

округляється до найближчого 32-бітного цілого числа, підписаного. Якщо значення знаходиться на півдорозі між двома цілими числами, повертається парне число; тобто 4,5 перетворюється на 4, а 5,5 перетворюється на 6.


7
Набагато краще, Math.Roundоскільки він повертає int у міру необхідності.
Кіт

10
@ robert-koritnik. Не впевнений, чому це "недійсно". OP не вказав переважне правило округлення, а "круглий .5 до найближчого парного" є стандартним правилом від зворотного шляху. Завжди округлення має небажані статистичні ефекти.
Кіт

@Keith: Я не знаю, але мене завжди вчили округляти х.5 вгору, але я бачу міркування робити це вгору або вниз для статистики. Дякую за це. PS Зрозуміло, що я не в статистиці, фінансах чи бухгалтерському обліку, де подібне округлення здається за замовчуванням .
Роберт Коритник

3
"Завжди округлення має небажані статистичні ефекти" - Це просто неправда. Округлення .5 вгору округляє рівно половину чисел - [0,.5)- вниз і рівно половину чисел - [.5,1)- вгору. Округлення до навіть злегка зміщених рівних чисел, оскільки воно крутиться (.5,1.5)до 1, але [1.5,2.5]до 2.
Джим Балтер

11
@JimBalter Оскільки нуль не округлюється, округлення наполовину вводить позитивний зміщення, таким чином, воно відоме як асиметричне округлення. "Равна половина до парної" не відповідає, якщо ваш розподіл рівний, а округлення не зміщує парних чи нерівномірних чисел. Дивіться на півсторонній округлення краватки .
sdds

36

Ви також можете використовувати функцію:

//Works with negative numbers now
static int MyRound(double d) {
  if (d < 0) {
    return (int)(d - 0.5);
  }
  return (int)(d + 0.5);
}

Залежно від архітектури це в кілька разів швидше.


Це було ідеально для мене, оскільки Math.Round працював не так, як я хотів.
Ганна

@cullub так. Він перетворює подвійний d, який додав до нього 0,5, у ціле число.
Даррелл

Це мій кращий метод - працює дуже просто. Настільки коротший і простіший для читання, ніж Math.Round (d, MidpointRounding.AwayFromZero) і більш стислий, ніж використання оператора if, щоб вибрати, чи слід округлювати чи округлювати. І, фактично повертає ціле число в кінці, а НЕ двічі
binderbound

3
Дивіться коментар @ Eternal21 нижче щодо непарної поведінки щодо негативних чисел (MyRound (-1.2) = 0)
Кріс

2
Для всіх, хто цікавиться, питання, про яке згадує @Chris, зараз, ймовірно, вирішується, перевіряючи, чи значення негативне.
Джон Вайс

14
double d;
int rounded = (int)Math.Round(d);

5

Я знаю, що це питання давнє, але я натрапив на нього в пошуках відповіді на моє подібне запитання. Я думав, що поділюсь дуже корисною порадою, яку мені дали.

Перетворюючи на int, просто додайте .5до вашої вартості перед тим, як скинути. У зв'язку з тим, що вихідний канал intзавжди опускається до нижчого числа (наприклад (int)1.7 == 1), якщо ваше число більше .5або вище, додавання .5призведе до наступного числа, а ваш знижений режим intповинен повернути правильне значення. (наприклад (int)(1.8 + .5) == 2)


13
Проблема полягає в тому, якщо ви спробуєте перетворити негативні значення таким чином. Наприклад, -1,25 в кінцевому підсумку дорівнює 0. (-1,25 + 0,5 = 0,75, а один раз знижений до int це 0). Тому потрібно відняти 0,5 від негативних значень.
Вічний21

Можна використовувати+ 0.5 * Math.Abs(d)
TaW


-1

Для Unity використовуйте Mathf.RoundToInt .

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.0f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.2f));
        // Prints 11
        Debug.Log(Mathf.RoundToInt(10.7f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.5f));
        // Prints 12
        Debug.Log(Mathf.RoundToInt(11.5f));

        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.0f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.2f));
        // Prints -11
        Debug.Log(Mathf.RoundToInt(-10.7f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.5f));
        // Prints -12
        Debug.Log(Mathf.RoundToInt(-11.5f));
    }
}

Джерело

public static int RoundToInt(float f) { return (int)Math.Round(f); }

Q не згадує та не позначає Unity.
XenoRo

@XenoRo Я відповідав на це давнє запитання для тих, хто шукає подібні відповіді під час використання Unity.
zwcloud

2
Ви можете відповісти на власні запитання для обміну знаннями. Створіть окреме запитання, характерне для API (у цьому випадку Unity) у таких випадках. Відповіді мають відповідати на питання. Інакше тут може бути відповідь на кожен C # API з функцією округлення.
XenoRo

-2

Я розробляю науковий калькулятор, на якому є кнопка Int. Я знайшов таке просте, надійне рішення:

double dblInteger;
if( dblNumber < 0 )
   dblInteger = Math.Ceiling(dblNumber);
else
   dblInteger = Math.Floor(dblNumber);

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


2
Чи не це округлює всі негативні і не знищує всі додатні числа? Це не обов'язково ціле число "Найближче".
Тім Польман

це не найближче число.
Самер Аамар

1
Враховуючи 1,99, це повертає 1,0.
Джон Шнайдер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.