Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как округлить число до N-го знака после запятой... 
:(
    Опции темы
chipset
Дата 28.3.2005, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



 Округление чисел
Используя функцию, приведённую ниже, можно округлить число типа double с требуемой точностью. Округлять можно по двум правилам:
1) то, чему нас учили в школе: если округляем до двух знаков после запятой, то сотые доли либо увеличиваются на 1, либо остаются без изменений - в зависимости от значений тысячных (если 4 тысячных - то оставляем сотые как есть, если больше 5-ти - увеличиваем сотые на 1, если 5 - то смотрим десятитысячные), все цифры правее сотых - отбрасываются;
2) простое отбрасывание всех цифр, правее указанной (если округляем до сотых, то тысячные и т.п. -- отбрасываются).

Для первого варианта округления, параметр nType должен быть равен ROUND_UP, для второго варианта - ROUND_TRIM. Параметр nPrecis задаёт количество знаков после запятой (номер цифры после запятой, до которой округляется число).
Код
#include "math.h"

#define ROUND_UP            1
#define ROUND_TRIM         2

const double Two=2, Five=5, Ten=10;
const double MaxPrecis=pow(10, 16);


[b]double Round(double Value, int nPrecis, int nType=ROUND_UP)[/b]
{
      if(nPrecis > 16 || !nPrecis) return Value;
      if(Value == 0) return Value;

      short wTmp;
    
      _asm
      {
            finit
            fstcw     wTmp
            mov     ax, wTmp      
            or        ax, 0000110000000000b   // RC=11 - trimming
            cmp      nType, ROUND_UP
            jne       m1
            and      ax, 1111001111111111b   // RC=00 - upper
m1:      mov      wTmp, ax
            fldcw    wTmp      
  
            fld         Value
            mov      ecx, nPrecis
            push      ecx
m2:      fmul      Ten
            loop      m2
  
            frndint
  
            pop      ecx
m3:      fdiv      Ten
            loop      m3
            fstp      Value
      }

      return Value;
}


Проверка "целое ли число"
Следующая функция возвращает true, если число целое (не имеет знаков правее запятой), и  false -- если дробное. Отличие данной функции от простого выражения   ((double)(int) fValue) ==  fValue ? true:false  состоит в том, что она позволяет работать с числами, бОльшими чем позволяет формат  int  (например, не зная точно, больше число по модулю, чем 2 триллиона, или нет - сложно определить, сработает ли выражение приведенное выше, требуется ещё рад проверок).

Итак, функция для проверки, целое или дробное число Value:
Код
#include "math.h"

[b]bool IsRounded(double Value)[/b]
{
      bool bResult = true; 
      short wTmp;
      _asm
      {
            finit
  
            fstcw      wTmp
            mov       ax, wTmp      
            or          ax, 0010110000000000b   // RC=11 - trimming, PC=11 - max precis
            mov       wTmp, ax
            fldcw       wTmp

            fld          Value
            fld          Value
            frndint
            fsub
            fxam

            fstsw      ax
            sahf
            je           end
            mov      bResult, 0
            jmp        end
  
end:      finit
      }

      return bResult;
}
 


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1103 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.