Допустим, у меня есть значение 3,4679, а мне нужно 3,46, как я могу усечь его до двух десятичных знаков без округления в большую сторону?
Я пробовал следующее, но все три дали мне 3,47:
void Main()
{
Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
Console.Write(Math.Round(3.4679, 2));
}
Это возвращает 3.46, но почему-то кажется грязным:
void Main()
{
Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
Было бы более полезно иметь полную функцию для реального использования усечения десятичной дроби в C #. Его можно довольно легко преобразовать в метод расширения Decimal, если хотите:
Если вам нужен VB.NET, попробуйте следующее:
Тогда используйте это так:
или
источник
Используйте оператор модуля:
результат: 0.54
источник
0.5400
... Ответ Д. Нестерова ниже дал ожидаемый0.54
.$"{0.54m:C}"
производит"$0.54"
и да,$"{0.5400m:C}"
производит"$0.54"
.Универсальный и быстрый метод (без
Math.Pow()
/ умножения) дляSystem.Decimal
:источник
Одна проблема с другими примерами заключается в том, что они умножают входное значение перед его делением. Здесь есть крайний случай, когда вы можете переполнить десятичное число, сначала умножив его, крайний случай, но кое-что, с чем я столкнулся. С дробной частью безопаснее разбираться отдельно следующим образом:
источник
Я оставлю решение для десятичных чисел.
Некоторые из представленных здесь решений для десятичных дробей склонны к переполнению (если мы передадим очень большое десятичное число, и метод попытается его умножить).
Решение Тима Ллойда защищено от переполнения, но не слишком быстро.
Следующее решение примерно в 2 раза быстрее и не имеет проблем с переполнением:
источник
Truncate
метод будет объединен с собственными .net, что дает пользователю беспроблемный опыт.Assert.AreEqual(1.1m, 1.12m.TruncateEx(1));
выходит из строя из-за этого. Если вы укажете «нормальное» округление (AwayFromZero) в вызове Math.Round, тоAssert.AreEqual(0m, 0m.TruncateEx(1));
не удастсяMidpointRounding.AwayFromZero
специальный код для обработки значения 0.Это старый вопрос, но многие ответы не работают или переполняются для больших чисел. Я считаю, что ответ Д. Нестерова самый лучший: надежный, простой и быстрый. Я просто хочу добавить свои два цента. Я поигрался с десятичными знаками, а также проверил исходный код . Из
public Decimal (int lo, int mid, int hi, bool isNegative, byte scale)
документации конструктора .Зная это, мой первый подход состоял в том, чтобы создать другой
decimal
, масштаб которого соответствует десятичным дробям, которые я хотел отбросить, затем усечь его и, наконец, создать десятичную дробь с желаемым масштабом.Этот метод не быстрее, чем у Д. Нестерова, и он сложнее, поэтому я еще немного поигрался. Я предполагаю, что необходимость создавать вспомогательный объект
decimal
и дважды извлекать биты делает его медленнее. Во второй попытке я сам манипулировал компонентами, возвращаемыми методом Decimal.GetBits (Decimal d) . Идея состоит в том, чтобы разделить компоненты на 10 столько раз, сколько необходимо, и уменьшить масштаб. Код основан (в значительной степени) на методе Decimal.InternalRoundFromZero (ref Decimal d, int decimalCount) .Я не проводил строгих тестов производительности, но на MacOS Sierra 10.12.6, процессоре Intel Core i3 3,06 ГГц и таргетинге на .NetCore 2.1 этот метод кажется намного быстрее, чем метод Д. Нестерова (я не буду приводить цифры, поскольку , как я уже упоминал, мои тесты не являются строгими). Тот, кто реализует это, должен оценить, окупается ли прирост производительности добавленной сложностью кода.
источник
это сработает для вас?
источник
Дала бы
((long)(3.4679 * 100)) / 100.0
то, что вы хотите?источник
Вот способ расширения:
источник
Если вы не слишком беспокоитесь о производительности и конечным результатом может быть строка, следующий подход будет устойчивым к проблемам с плавающей точностью:
источник
Вот моя реализация функции TRUNC
источник
как насчет этого?
источник
Помимо вышеперечисленных решений, мы можем добиться еще одним способом.
источник
В некоторых случаях этого может быть достаточно.
У меня было десятичное значение SubCent = 0,00999999999999999999999999M, которое имеет тенденцию форматироваться в | SubCent: 0,010000 | via
string.Format("{0:N6}", SubCent );
и многие другие варианты форматирования.Моим требованием было не округлять значение SubCent, но и не регистрировать каждую цифру.
Следующее отвечало моим требованиям:
Что возвращает строку: | SubCent: 0.0099999 |
Чтобы учесть значение, имеющее целую часть, начнем с того, что нужно.
Что возвращает строку:
источник
я использую эту функцию для усечения значения после десятичного числа в строковой переменной
источник
Вот что я сделал:
вычитание двух введенных чисел без округления десятичных знаков в большую или меньшую сторону. потому что другие решения мне не подходят. не знаю, сработает ли это для других, я просто хочу поделиться этим :) Надеюсь, это сработает для тех, кто находит решение проблемы, похожей на мою. Спасибо
PS: я новичок, поэтому не стесняйтесь указывать на что-нибудь по этому поводу. : D это хорошо, если вы действительно имеете дело с деньгами, из-за центов, не так ли? у него только 2 десятичных знака, а округление - нет.
источник
источник
источник
На самом деле вы хотите 3.46 из 3.4679. Это всего лишь представление символов. Так что здесь нет ничего общего с математической функцией. Математическая функция не предназначена для этой работы. Просто используйте следующий код.
источник
что о
источник