Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Double |
Автор: Dmi3ev 24.5.2008, 08:47 |
Столкнулся с такой проблемой: беру число (тип переменной double), например 0,03, это число сложно представить в двоичной системе(комп ведь в ней работает) (что-то вроде если 1/3 в десятичной представлять, то период получится), поэтому после некоторых действий оно либо немного больше, либо немного меньше того числа, которое получается на самом деле. Я написал свою функцию, которая, так сказать, округляет это дело, как мне надо. Но, интересно, можно это сделать как-нибудь по умному? Подскажите, пожалуйста. Или я заблуждаюсь на счет того, что это из-за двоичной системы счисления? |
Автор: Ken 24.5.2008, 09:50 |
Можете работать прямо с рациональными числами, например, опередлить класс Rational, переопределить арифметические операции и перобразование к типу double и т.д. |
Автор: Dmi3ev 24.5.2008, 09:55 | ||
это я понимаю, но, если я после некоторых операций должен получить в дробной части 0,12, то я получаю 0,119999..., причем, это происходит, когда в целой части большое число, например, 123456. вообщем, какая-то ерунда. я поэтому и спрашиваю. |
Автор: Ken 24.5.2008, 10:03 | ||
Из за ограниченности количество разрядов для представления чисел в памяти вы часто получете такие ошибки. Поэтому вам надо все время округлять результат до какой-то точности. Из за этого даже операция проверки чисел с плавающей запятой на равенство часто дает неверный результат. Т.е. нельзя использовать запись типа a == b для таких типов. |
Автор: Dmi3ev 24.5.2008, 10:04 |
Ken, можно и так решить проблему (я функцию написал, ты класс предлагаешь), но, наверняка, есть способ, который до нас придуман, я и хочу узнать его. |
Автор: bronislav 24.5.2008, 10:15 |
Способ был предложен выше. Использовать свой класс для таких расчетов и там реализовать необходимую точность. |
Автор: Ken 24.5.2008, 10:18 | ||
Если нужно представление рационального числа со 100% точностью, то способ один: хранить в виде пар чисел. На счет класса, я попробую предложить пример реализации. Пока, если вам просто надо сравнивать 2 числа на (примерное) равенство пишите так: abs (a - b) < epsilon здесь a и b числа с плавающей запятой, а epslion погрешность (положительное число ближу к 0). |
Автор: mes 24.5.2008, 10:23 | ||||
Да, это не из за двоичной системы счисления, а в из за способа представления числа в памяти.
используйте тип с фиксированной запятой |
Автор: Ken 25.5.2008, 08:42 | ||
И так, обещал представить решение, но кажется до нас это уже сделали и несколько раз. Смотрите сюда: http://www.geekpedia.com/tutorial222_Overloading-Operators-Creating-a-Rational-Class.html http://solarix.ru/for_developers/cpp/boost/rational/ru/rational.shtml |
Автор: bronislav 25.5.2008, 09:08 |
Вот это решение мне нравиться больше. |
Автор: ksili 26.5.2008, 10:51 |
Можно задать режим округления чисел. Операции с вещественными числами выполняет FPU (Floating point unit) поэтому этот режим задается в его флагах. Всего там 4 режима: к нулю к минус бесконечности к плюс бесконечности к ближайшему числу Наверняка ваш компилятор сам задает какой-то режим по -умолчанию. Как задать режим на ассемблере мне понятно, могу посмотреть как именно и позже написать (можете сами посмотреть книгу Зубкова по асму в разделе про FPU). А вот на С++ не знаю. Возможно придётся делать ассемблерную вставку. |
Автор: Dmi3ev 29.5.2008, 00:29 |
спасибо за помощь всем, проблему считаю решенной, мы докопались до истины, а точнее вы))) Ken, отдельное спасибо, больше всех старался))) |