Как мне преобразовать десятичную в целое?
Как мне преобразовать десятичную в целое?
Ответы:
Используйте Convert.ToInt32
из , mscorlib
как в
decimal value = 3.14m;
int n = Convert.ToInt32(value);
Смотрите MSDN . Вы также можете использовать Decimal.ToInt32
. Опять же, смотрите MSDN . Наконец, вы можете сделать прямой бросок, как в
decimal value = 3.14m;
int n = (int) value;
который использует явный оператор приведения. Смотрите MSDN .
null
сравнению 0
с ""
). Я бы рекомендовал никогда не использовать Convert, если вам абсолютно не нужна его гибкость (то есть в динамически типизированных сценариях)
OverflowException
. Я считаю, что @Will дает лучший ответ здесь stackoverflow.com/a/501165/39532
Convert.ToInt32
и Decimal.ToInt32
ведите себя по-другому. Из MSDN: Decimal.ToInt32
- возвращаемое значение является неотъемлемой частью десятичного значения; дробные цифры усекаются . Convert.ToInt32
- Возвращаемое значение округляется до ближайшего 32-разрядного целого числа со знаком. Если значение находится посередине между двумя целыми числами, возвращается четное число; то есть 4,5 преобразуется в 4, а 5,5 преобразуется в 6.
Ты не можешь
Ну, конечно, вы могли бы , однако int (System.Int32) недостаточно велик, чтобы содержать все возможные десятичные значения.
Это означает, что если вы приведете десятичное число, которое больше, чем int.MaxValue, вы переполнитесь, а если десятичное число будет меньше, чем int.MinValue, оно опустится.
Что происходит, когда вы находитесь под / переполнение? Одна из двух вещей. Если ваша сборка не проверена (т. Е. CLR не волнует, если вы это сделаете), ваше приложение продолжит работу после того, как значение превысит / понизит значение, но значение в int будет не тем, что вы ожидали. Это может привести к периодическим ошибкам и может быть трудно исправить. В конечном итоге ваше приложение окажется в неизвестном состоянии, что может привести к повреждению вашего приложения какими-либо важными данными, над которыми он работает. Не хорошо.
Если ваша сборка проверена (свойства-> build-> advanced-> проверка на арифметическое переполнение / недополнение или параметр / checked компилятора), ваш код сгенерирует исключение при возникновении недостаточного / переполнения. Это, вероятно, лучше, чем нет; однако по умолчанию для сборок не выполняется проверка на переполнение / переполнение.
Настоящий вопрос - «что ты пытаешься сделать?» Не зная ваших требований, никто не может сказать вам, что вы должны делать в этом случае, кроме очевидного: НЕ ДЕЛАЙТЕ ЭТОГО.
Если вам не все равно, ответы здесь действительны. Тем не менее, вы должны сообщить о своем понимании того, что может произойти переполнение и что это не имеет значения, оборачивая ваш приведенный код в непроверенный блок
unchecked
{
// do your conversions that may underflow/overflow here
}
Таким образом, люди, идущие за вами, понимают, что вам все равно, и если в будущем кто-то изменит ваши сборки на / флажок, ваш код не будет неожиданно сломан.
Если все, что вы хотите сделать, это отбросить дробную часть числа, оставив неотъемлемую часть, вы можете использовать Math.Truncate.
decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));
int i = (int)d;
даст вам число, округленное в меньшую сторону.
Если вы хотите округлить до ближайшего четного числа (т.е.> .5 округлится вверх), вы можете использовать
int i = (int)Math.Round(d, MidpointRounding.ToEven);
В общем, вы можете привести между всеми числовыми типами в C #. Если нет информации, которая будет потеряна во время приведения, вы можете сделать это неявно:
int i = 10;
decimal d = i;
хотя вы можете сделать это явно, если хотите:
int i = 10;
decimal d = (decimal)i;
Тем не менее, если вы собираетесь потерять информацию через актерский состав, вы должны сделать это явно (чтобы показать, что вы знаете, что вы можете потерять информацию):
decimal d = 10.5M;
int i = (int)d;
Здесь вы теряете ".5". Это может быть хорошо, но вы должны четко заявить об этом и сделать явное приведение, чтобы показать, что вы можете потерять информацию.
ToEven
следует предотвратить смещение статистики. Однако если вы работаете с платными предметами или деньгами, это AwayFromZero
кажется правильным выбором.
decimal vIn = 0.0M;
int vOut = Convert.ToInt32(vIn);
Вот очень удобная конвертируемая страница типа данных для других. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
System.Decimal
реализует IConvertable
интерфейс, который имеетToInt32()
член.
Звонок System.Decimal.ToInt32()
работает для вас?
Аккуратный трюк для быстрого округления состоит в том, чтобы добавить .5, прежде чем вы приведете десятичное число к int.
decimal d = 10.1m;
d += .5m;
int i = (int)d;
Еще уходит i=10
, но
decimal d = 10.5m;
d += .5m;
int i = (int)d;
Собрался бы так, что i=11
.
Я предпочитаю использовать Math.Round , Math.Floor , Math.Ceiling или Math.Truncate чтобы явно установить режим округления в зависимости от ситуации.
Обратите внимание, что все они также возвращают Decimal - поскольку Decimal имеет больший диапазон значений, чем Int32, поэтому вам все равно придется приводить (и проверять наличие переполнения / потери значения).
checked {
int i = (int)Math.Floor(d);
}
Округление десятичной дроби до ближайшего целого
decimal a ;
int b = (int)(a + 0.5m);
когда a = 49.9
тогдаb = 50
когда a = 49.5
тогдаb = 50
когда a = 49.4
, то b = 49
и т. д.
Я считаю, что оператор приведения не работает, если у вас есть десятичное число в штучной упаковке (то есть десятичное значение внутри типа объекта). Convert.ToInt32 (десятичный как объект) прекрасно работает в этом случае.
Эта ситуация возникает при получении значений IDENTITY / AUTONUMBER из базы данных:
SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works
int ID = (int)foo.ExecuteScalar(); // throws InvalidCastException
SELECT SCOPE_IDENTITY()
возвращает, numeric(38, 0)
что переводит на decimal
.NET. foo.ExecuteScalar()
возвращает в decimal
штучной упаковке, object
который не может быть приведен непосредственно к int
. (int)(decimal)foo.ExecuteScalar()
или Convert.ToInt32(foo.ExecuteScalar())
будет работать.
Кажется, что ни один ответ не имеет отношения к OverflowException / UnderflowException, возникающему при попытке преобразовать десятичное число, выходящее за пределы диапазона int.
int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));
Это решение вернет максимальное или минимальное возможное значение типа int, если десятичное значение находится вне диапазона int. Возможно, вы захотите добавить некоторые округления с Math.Round, Math.Ceiling или Math.Floor для случаев, когда значение находится внутри диапазона int.