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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Double 
V
    Опции темы
Dmi3ev
Дата 24.5.2008, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 1
Всего: 41



Столкнулся с такой проблемой: беру число (тип переменной double), например 0,03, это число сложно представить в двоичной системе(комп ведь в ней работает) (что-то вроде если 1/3 в десятичной представлять, то период получится), поэтому после некоторых действий оно либо немного больше, либо немного меньше того числа, которое получается на самом деле. Я написал свою функцию, которая, так сказать, округляет это дело, как мне надо. Но, интересно, можно это сделать как-нибудь по умному? Подскажите, пожалуйста. Или я заблуждаюсь на счет того, что это из-за двоичной системы счисления?


--------------------

PM MAIL   Вверх
bronislav
Дата 24.5.2008, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: нет
Всего: 3



Цитата(Dmi3ev @  24.5.2008,  08:47 Найти цитируемый пост)
либо немного больше, либо немного меньше того числа, которое получается на самом деле

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

А числа с плавающей точкой в двоичной системе счисления представляются отдельно целаю часть, отдельно дробная. А в памяти компьютера записываются еще интересней.




--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
Ken
Дата 24.5.2008, 09:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Можете работать прямо с рациональными числами, например, опередлить класс Rational, переопределить арифметические операции и перобразование к типу double и т.д.
PM MAIL   Вверх
Dmi3ev
Дата 24.5.2008, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 1
Всего: 41



Цитата

А числа с плавающей точкой в двоичной системе счисления представляются отдельно целаю часть, отдельно дробная.

это я понимаю, но, если я после некоторых операций должен получить в дробной части 0,12, то я получаю 0,119999..., причем, это происходит, когда в целой части большое число, например, 123456. вообщем, какая-то ерунда. я поэтому и спрашиваю. 


--------------------

PM MAIL   Вверх
Ken
Дата 24.5.2008, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Цитата(Dmi3ev @ 24.5.2008,  09:55)
это я понимаю, но, если я после некоторых операций должен получить в дробной части 0,12, то я получаю 0,119999..., причем, это происходит, когда в целой части большое число, например, 123456. вообщем, какая-то ерунда. я поэтому и спрашиваю.

Из за ограниченности количество разрядов для представления чисел в памяти вы часто получете такие ошибки. Поэтому вам надо все время округлять результат до какой-то точности. Из за этого даже операция проверки чисел с плавающей запятой на равенство часто дает неверный результат. Т.е. нельзя использовать запись типа a == b для таких типов.

Это сообщение отредактировал(а) Ken - 24.5.2008, 10:05
PM MAIL   Вверх
Dmi3ev
Дата 24.5.2008, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 1
Всего: 41



Ken, можно и так решить проблему (я функцию написал, ты класс предлагаешь), но, наверняка, есть способ, который до нас придуман, я и хочу узнать его.


--------------------

PM MAIL   Вверх
bronislav
Дата 24.5.2008, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: нет
Всего: 3



Способ был предложен выше. Использовать свой класс для таких расчетов и там реализовать необходимую точность.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
Ken
Дата 24.5.2008, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Цитата(Dmi3ev @ 24.5.2008,  10:04)
Ken, можно и так решить проблему (я функцию написал, ты класс предлагаешь), но, наверняка, есть способ, который до нас придуман, я и хочу узнать его.

Если нужно представление рационального числа со 100% точностью, то способ один: хранить в виде пар чисел. На счет класса, я попробую предложить пример реализации. Пока, если вам просто надо сравнивать 2 числа на (примерное) равенство пишите так:

abs (a - b) < epsilon

здесь a и b числа с плавающей запятой, а epslion погрешность (положительное число ближу к 0).

Это сообщение отредактировал(а) Ken - 24.5.2008, 10:28
PM MAIL   Вверх
mes
Дата 24.5.2008, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Dmi3ev @  24.5.2008,  08:47 Найти цитируемый пост)
Или я заблуждаюсь на счет того, что это из-за двоичной системы счисления? 

Да, это не из за двоичной системы счисления, а в из за способа представления числа в памяти. 

Цитата(Dmi3ev @  24.5.2008,  09:55 Найти цитируемый пост)
это я понимаю, но, если я после некоторых операций должен получить в дробной части 0,12, то я получаю 0,119999..., причем, это происходит, когда в целой части большое число, например, 123456. вообщем, какая-то ерунда. я поэтому и спрашиваю.  

используйте тип с фиксированной запятой 


--------------------
PM MAIL WWW   Вверх
Ken
Дата 25.5.2008, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Цитата(Dmi3ev @ 24.5.2008,  10:04)
Ken, можно и так решить проблему (я функцию написал, ты класс предлагаешь), но, наверняка, есть способ, который до нас придуман, я и хочу узнать его.

И так, обещал представить решение, но кажется до нас это уже сделали и несколько раз. Смотрите сюда:

http://www.geekpedia.com/tutorial222_Overl...onal-Class.html
http://solarix.ru/for_developers/cpp/boost.../rational.shtml

PM MAIL   Вверх
bronislav
Дата 25.5.2008, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: нет
Всего: 3



Цитата(Ken @  25.5.2008,  07:42 Найти цитируемый пост)
http://solarix.ru/for_developers/cpp/boost.../rational.shtml


Вот это решение мне нравиться больше.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
ksili
Дата 26.5.2008, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Можно задать режим округления чисел. Операции с вещественными числами выполняет FPU (Floating point unit) поэтому этот режим задается в его флагах. Всего там 4 режима:
к нулю
к минус бесконечности
к плюс бесконечности
к ближайшему числу
Наверняка ваш компилятор сам задает какой-то режим по -умолчанию. Как задать режим на ассемблере мне понятно, могу посмотреть как именно и позже написать (можете сами посмотреть книгу Зубкова по асму в разделе про FPU). А вот на С++ не знаю. Возможно придётся делать ассемблерную вставку.


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Dmi3ev
Дата 29.5.2008, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 1
Всего: 41



спасибо за помощь всем, проблему считаю решенной, мы докопались до истины, а точнее вы)))

Ken, отдельное спасибо, больше всех старался)))


--------------------

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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