![]() |
|
Модераторы: bsa |
![]()
|
|
| IKM2007 |
|
||||
![]() Зима близко ![]() ![]() Профиль Группа: Участник Сообщений: 702 Регистрация: 26.4.2008 Где: olmedreca Репутация: 3 Всего: 40 |
Добрый день всем,
ответьте вот на такой вопрос. Как выполняется прибавление или убавление чисел типа double. Вот на примере.
то есть условие (4.2-3.2<2.2-1.2) верно. Но вот...
то есть ни одно условие не верно. Может кто нибудь обяснит мне, что здесь творится? -------------------- "К чёрту обстоятельства, я создаю возможности." Брюс Ли |
||||
|
|||||
| rrrFer |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 208 Регистрация: 11.5.2008 Где: Красноярск Репутация: 0 Всего: 1 |
ИМХО парадокс
интересно что:
a 4.2000000000000002 double b 3.2000000000000002 double c 2.2000000000000002 double d 1.2000000000000000 double вообще погрешности большие почему-то: если написать
то в функцию f передано: a 1.2000000000000000 double b 0.20000000000000001 double c 1.3000000000000000 double d 0.29999999999999999 double Это сообщение отредактировал(а) rrrFer - 14.5.2008, 17:27 |
||||
|
|||||
| anatox91 |
|
|||
![]() программист-самоучка ![]() ![]() Профиль Группа: Участник Сообщений: 699 Регистрация: 12.1.2008 Где: ++Украина.Крым++ Репутация: 1 Всего: 13 |
мдаа.. попробовал - действительно...
-------------------- The code is the design © Sony VAIO VGN-FW480J ![]() |
|||
|
||||
| rrrFer |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 208 Регистрация: 11.5.2008 Где: Красноярск Репутация: 0 Всего: 1 |
а еще вот что получилось:
при вводе числа 2.5 все нормально, погрешности не видно вообще, а вот если ввести 1.2.... |
|||
|
||||
| Gradov |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: нет Всего: 3 |
Числа с плавающей запятой необходимо сравнивать только предварительно переведя их в строковую переменную. И уже после этого сравнивать строки а не числа с плавающей запятой! Данная операция необходима для исключения погрешностей, которые возникают из-за особенностей самого формата хранения чисел с плавающей запятой. |
|||
|
||||
| JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 6 Всего: 162 |
Феерическая фигня. Перевод в строковую форму занимает туеву хучу процессорного времени. Сравнение чисел с плавающей точкой можно сравнивать только с учётом допуска некой малой величины E. То есть, к примеру:
Само собой, E выбирается в зависимости от нужной точности и алгоритма. |
|||
|
||||
| nickless |
|
||||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 2 Всего: 181 |
Просто сравнивать надо с погрешностью эпсилон, например так:
Просто числа хранятся в двоичном виде, по этому число 1.2 = 1 + 1/5 точно представить невозможно, можно только приближенно. Например в double точность мантиссы 52 бит, т.е. погрешность будет где-то +- 0.5 * 1/(2^52) ~ 1.110223e-16 Это сообщение отредактировал(а) nickless - 14.5.2008, 19:18 -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
||||||
|
|||||||
| archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
Ещё, варианты:
1. Написать класс-обёртку над double(в идеале, над произвольным типом T), который будет проделывать операции сравнения с заданной точностью автоматически. 2. Использовать арифметику с бесконечной точностью(т.н. exact types): GMP, boost::rational, CGAL::Quotient, CGAL::Gmpzf(обёртка над gmp_mpf_class) и пр. 3. Использовать арифметику с неограниченной, но, задаваемой точностью(преимущество в том, что в отличии от exact types с ними можно проделывать такие операции, по определению невозможные для exact types как то sin, cos, sqrt, etc.): MPFR, mpfr::Real(С++ обёртка из MPFR_CPP). Ссылки на все вышеупомянутые классы/библиотеки можно нарыть в гугле. ЗЫ. Помню, как лет 5 назад я матерился на Delphi, когда обнаружил в нём "ошибку" из-за которой иногда получается отрицательный ноль из-за чего не работала вычислительная часть одного из моих проектов На самом деле - это всего лишь отрицательное бесконечно малое, которое, кстати тоже является почвой для долгих поисков мифического бага -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
| IKM2007 |
|
|||
![]() Зима близко ![]() ![]() Профиль Группа: Участник Сообщений: 702 Регистрация: 26.4.2008 Где: olmedreca Репутация: 3 Всего: 40 |
Всем Большое Спасибо, все понятно.
-------------------- "К чёрту обстоятельства, я создаю возможности." Брюс Ли |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Сугубо точности ради |
|||
|
||||
| archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 6 Всего: 93 |
Если мне не изменяет память, этот самый отрицательный ноль и интерпретируется как отрицательное бесконечно малое... Разве нет? -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Нет.
Integer - implied (not stored) Это сообщение отредактировал(а) xvr - 15.5.2008, 13:26 |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |