Главная страница > Вопрос
Вопрос
Округление числа в С# до n значимых цифр
...и усечение
программирование | C# 25.09.08 Автор: VAlexius
Ответы
1 из 10
Пользуйтесь MSDN.
25.09.08 Автор: Agni
2 из 10
Перегрузка для n-значимых тут: [1].
25.09.08 Автор: Agni
3 из 10
Может функции С++ подойдут:
celi(x*pow(10,n))/pow(10,n)
или
floor(x*pow(10,n))/pow(10,n)
25.09.08 Автор: Ярость хомячка
4 из 10
*ceil
25.09.08 Автор: Ярость хомячка
5 из 10
Math.Round(x, n); // округление
Math.Truncate(x * Math.Pow(10, n)) / Math.Pow(10, n); // усечение

где x - данное число, n - необходимое количество цифр после запятой
25.09.08 Автор: Harm
6 из 10
Можно так для экономии размера кода:

y = int(x*10^n)/10^n

где x - исходное число, n - количество знаков после запятой, которые надо оставить.
Суть - умножаем на кол-во 10-ков, округляем, возвращаем назад.
Примечание: Но надо проверять, возможно при больших n (>12) будет глючить.
25.09.08 Автор: mahinder_suresh
7 из 10
mahinder_suresh,
1. Зачем там применять XOR -- неизвестно, даже не смотря на явное указание, мол, давайте будем считать это возведением в степень.
2. Синтаксис VB-like, что тоже не гут.
3. Условие при n > 12 (где 12 -- магическое число) -- тоже не очень. Лучше полагаться на библиотечные функции, а не изобретать велосипед заново.
4. Самое интересное. Сомнительно преимущество экономии места в сорсах. Посмотрим, что же делает на самом деле компилятор VB.NET. Есть код:
Sub Main()
   Dim y As Integer
   Const x = 5.66
   Const n = 4
   y = Int(x * 10 ^ n) / 10 ^ n
   Console.WriteLine(y)
End Sub
Теперь пройдёмся .NET Reflector по сборке в метод Main, используя генератор кода VB.NET:
Public Shared Sub Main()
   Dim y As Integer = CInt(Math.Round(CDbl((Conversion.Int(CDbl(56600)) / 10000))))
   Console.WriteLine(y)
End Sub
Как видим, дела обстоят не очень-то и хорошо. Вопрос состоит в следующем: поскольку в действительности, мало того, что компилятор генерирует не сильно оптимизированный код (ещё Алэн И. Голуб в своей «Enough Rope to Shoot Yourself in the Foot: Rules for C and C++ Programming» чётко показал, почему *компьютеры не знают математики*), так ещё используется и совсем неявная математическая конструкция, которая не слишком читаема сначала, а требует предварительного анализа, то есть ли смысл запутывать код и снижать производительность в общем (благо, не используются циклы)?

В действительности лучше использовать чёткий для читания код, контролируя выполнение каждой операции, не заставляя компилятор генерировать «тяжёлый код». Поэтому:
1) Для округления -- Math.Round(...)
2) Для усечения -- Math.Floor(...)
25.09.08 Автор: Цыба
8 из 10
Да, кстати, Math.Truncate также.
25.09.08 Автор: Цыба
9 из 10
Значащими цифрами числа называют все цифры в его записи, начиная с первой ненулевой цифры слева.

   static double RoundSign(double x, int n)
   {
     int digits = n - (int)Math.Log10(x) - 1;
     if (x < 1) digits++;
     return Math.Round(x * Math.Pow(10, digits)) / Math.Pow(10, digits);
   }

   static double TruncateSign(double x, int n)
   {
     int digits = n - (int)Math.Log10(x) - 1;
     if (x < 1) digits++;
     return Math.Truncate(x * Math.Pow(10, digits)) / Math.Pow(10, digits);
   }

Результаты:
RoundSign(1.253, 2) = 1.3
TruncateSign(1.253, 2) = 1.2
RoundSign(0.00126, 2) = 0.0013
TruncateSign(0.00126, 2) = 0.0012
TruncateSign(0.00010098, 3) = 0.0001
RoundSign(0.00010098, 3) = 0.000101
26.09.08 Автор: Harm
10 из 10
"Индийский" способ округления до 4-х знаков после запятой:

double d = 1902 / 7.0;
double d_trunc = double.Parse(d.ToString(".0000"));


Кстати, зачем вам это могло понадобиться?
26.09.08 Автор: hardcase
Это может быть интересно
как округлять числа с недостатком
Как ограничить количество знаков числа после запятой без округления C++
Какое наименьшее целое положительно число может быть написано двумя цифрами?
Математика. Деление 17 на 9. Почему нет периода на калькуляторах?
окончательная сумма цифр факториала числа
Войти
Просмотреть Вопросы и ответы в версии: для мобильных устройств | для ПК
©2014 Google - Политика конфиденциальности - Справка