Как я могу преобразовать двойное в ближайшее целое значение?

Ответы:

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
nickf
источник
6
Не будет Convert.ToInt32()делать то же самое, или это просто лишить все после десятичной дроби?
Человек Маффин
208
На самом деле не производит целое число, а удваивает.
gatopeich
13
@ Ронни - нет, это по замыслу. По умолчанию 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
@ роберт-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);
}

В зависимости от архитектуры это в несколько раз быстрее.

szymcio
источник
Это было идеально для меня, так как Math.Round работал не так, как я хотел.
Ханна
@cullub да, это так. Он преобразует двойное d, к которому добавлено 0,5, в целое число.
Даррелл
Это мой предпочтительный метод - работает очень просто. Намного короче и проще для чтения, чем Math.Round (d, MidpointRounding.AwayFromZero) и более кратким, чем использование оператора if для выбора, округлять или округлять. И, фактически возвращает целое число в конце, а не дважды
binderbound
3
Смотрите ниже комментарий @ Eternal21 о странном поведении отрицательных чисел (MyRound (-1.2) = 0)
Крис
2
Для всех, кто интересуется, проблема, упомянутая @Chris, теперь, по-видимому, решается путем проверки, является ли значение отрицательным.
Джон Вайс
5

Я знаю, что этот вопрос старый, но я наткнулся на него в поисках ответа на мой похожий вопрос. Я думал, что поделюсь очень полезным советом, который мне дали.

При конвертации в int просто добавьте .5свою ценность перед понижением. Так как значение downcasting intвсегда опускается до меньшего числа (например (int)1.7 == 1), если ваш номер больше .5или больше, добавление .5переведет его в следующий номер, и ваш downcast intдолжен вернуть правильное значение. (например (int)(1.8 + .5) == 2)

Трент
источник
13
Проблема в том, что если вы попытаетесь преобразовать отрицательные значения таким образом. Например, -1.25 получится равным 0. (-1.25 + 0.5 = 0.75, а однажды приведенный к int равен 0). Таким образом, вы должны вычесть 0,5 из отрицательных значений.
Eternal21
Можно использовать+ 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); }
zwcloud
источник
Q не упоминает и не помечает Unity.
XenoRo
@XenoRo Я отвечал на этот старый вопрос для тех, кто ищет похожие ответы при использовании Unity.
zwcloud
2
Вы можете ответить на свои вопросы для обмена знаниями. Создайте отдельный вопрос, специфичный для API (в данном случае Unity) в подобных случаях. Ответы должны быть соотнесены с вопросами. В противном случае здесь может быть ответ для каждого API C # с функцией округления.
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.
Джон Шнайдер