2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4  След.
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение15.03.2014, 22:00 
Заслуженный участник


28/04/09
1933
whitefox
whitefox в сообщении #836787 писал(а):
Имхо, достаточно (x == 0)
Смотря с какой стороны посмотреть. С точки зрения корректности программы $\text{---}$ достаточно. С точки зрения хорошего стиля кодирования лучше избегать неявного преобразования типов для констант, т.е. объявлять константы того типа, который подразумевается по логике работы программы. А именно: 0.0 $\text{---}$ double, 0.0f $\text{---}$ float, 0.0L $\text{---}$ long double, 0 $\text{---}$ int, 0L $\text{---}$ long и т.д. В данном случае число типа double сравнивается с константой, которую лучше объявить как константу типа double $\text{---}$ 0.0.

bin
bin в сообщении #836667 писал(а):
ИМХО все сравнения на равенство для чисел с плавающей запятой вне зависимости от применяемого языка осуществляются по формуле $|x-y|< \varepsilon $, т.о. ИМХО нужно выбрать точность $\varepsilon$ в зависимости от применяемого формата double
Это неправильно, как мне кажется. Даже безотносительно того, что в каких-то особенно редких случаях может потребоваться прямое сравнение на равенство. Прежде всего, $\varepsilon$ должно зависеть не только от применяемого формата, но и от характерных величин сравниваемых значений. Т.е. в общем случае лучше использовать не абсолютную, а относительную погрешность:$$\frac{|x-y|}{\max(|x|, |y|)}<\delta.$$К сожалению, такой подход нельзя распространить на весь диапазон "компьютерных" вещественных чисел, при приближении сравниваемых чисел к нулю с ним начинаются проблемы (2 ближайших к нулю числа одного знака дадут значение погрешности $0{,}5$, разных знаков $\text{---}$ аж $2$). Поэтому близкие к нулю числа лучше сравнивать все-таки с использованием абсолютной погрешности: $|x-y|< \varepsilon$. Эти две области сравнения надо как-то сопрячь. В самом простом случае можно взять некое "граничное" число $\tilde m=\varepsilon/\delta$. Если $m=\max(|x|,|y|)\le \tilde m$, то использовать для сравнения абсолютную погрешность. В противном случае $\text{---}$ относительную. При этом предварительно нужно проверить некоторые особые варианты (NaN'ы, бесконечности). Таким образом, процедура сравнения будет зависеть от двух вспомогательных параметров ($\varepsilon$ и $\delta$), которые нужно либо заранее знать (основываясь на некой предварительной информации о порядках сравниваемых величин), либо вычислять в процессе выполнения программы на основе полученных ею данных.
Помимо такого "универсального" способа сравнения вещественных чисел есть принципиально иной механизм. Он основывается на интересной особенности стандарта IEEE 754, благодаря которой арифметический порядок вещественных чисел соответствует лексикографическому порядку их битовых представлений (для любых вещественных чисел, включая бесконечности и исключая NaN'ы и нули, $x_1<x_2\Leftrightarrow i_1<i_2$, где $i_1$ и $i_2$ $\text{---}$ целочисленные интерпретации битовых представлений вещественных чисел $x_1$ и $x_2$). В данном случае при сравнении чисел задается только один (целочисленный) параметр $\text{---}$ наибольшее допустимое количество ульпов между сравниваемыми числами. Для нормализованных чисел это равносильно заданию относительной погрешности, а для денормализованных $\text{---}$ абсолютной. Но, в отличие от предыдущего метода, сравнение (даже с учетом дополнительных нюансов) производится значительно быстрее.

Yuri Gendelman
Yuri Gendelman в сообщении #836837 писал(а):
В качестве платформозависимой оценки $\varepsilon$ иногда рекомендуется максимальное $MAXEPS$ такое, что
$(1 + MAXEPS) == 1$ .
Yuri Gendelman в сообщении #837184 писал(а):
Это как в преферансе: "Хода нет - ходи с бубей".
Но ведь такое сравнение заведомо бессмысленно для чисел, больших единицы (или двух, если используется другое машинное эпсилон) по абсолютной величине.

Skeptic
Skeptic в сообщении #837197 писал(а):
При делении на 0 система выдаст ошибку с определённым кодом.
Какую систему Вы имеете в виду? Обычно при делении (отличного от нуля) числа на нуль получается бесконечность.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение15.03.2014, 22:40 
Заслуженный участник


15/05/05
3445
USA
EtCetera,

Здесь я неверно описал рекомендуемую поправку ("пррроклятые годы!" (с)):
Yuri Gendelman в сообщении #836837 писал(а):
В качестве платформозависимой оценки $\varepsilon$ иногда рекомендуется максимальное MAXEPS такое, что
(1 + MAXEPS) == 1
.

Должно быть:
Цитата:
В качестве платформозависимой оценки $\varepsilon$ иногда рекомендуется минимальное $MINEPS$ такое, что
$(1 + MINEPS) > 1$ .

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

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение15.03.2014, 23:01 
Заслуженный участник


28/04/09
1933
Yuri Gendelman
Честно говоря, я не вижу, как Ваше исправление принципиально меняет ситуацию. Разница чисел, больших 2 по абсолютной величине, всегда заведомо больше такого $MINEPS$.
Yuri Gendelman в сообщении #837316 писал(а):
Использовать при сравнении чисел относительную погрешность я никому не рекомендую. Во всяком случае как стандартный прием. Особенно в промышленных системах.
Почему?

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение16.03.2014, 07:07 


01/12/11

1047
Деление на 0 определяется на самом низком машинном уровне. Все системы программирования, начиная с машинного языка, могут (обязаны) воспринимать эту ситуацию и содержать необходимые средства индикации и обработки. Логичнее воспользоваться встроенной системой обработки сбойных ситуаций, чем программировать её заново - это более эффективно и профессионально.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение16.03.2014, 20:33 
Заслуженный участник


15/05/05
3445
USA
EtCetera

EtCetera в сообщении #837325 писал(а):
Yuri Gendelman
Честно говоря, я не вижу, как Ваше исправление принципиально меняет ситуацию.
Я просто исправил свою ошибку в описании платформо-зависимой константы.
Вы правы, ситуацию это не меняет.

EtCetera в сообщении #837325 писал(а):
Yuri Gendelman в сообщении #837316 писал(а):
Использовать при сравнении чисел относительную погрешность я никому не рекомендую. Во всяком случае как стандартный прием...
Почему?
При вычислении относительной погрешности всегда есть шанс получить overflow при делении. Приходится это учитывать, добавляя try -- catch. (И применять абс.погр. в catch-блоке!)

Потому я и говорю о стандартном приеме, когда нет других доводов за или против.
Но помнить про относительную погрешность нужно. В этом я с Вами согласен.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение17.03.2014, 14:09 
Аватара пользователя


22/09/09

1907
Общеизвестно, что за все приходится платить, но плата должна быть разумной. Обычному калькулятору не нужны слишком большие точность и скорость, поэтому можно взять $\varepsilon$ не слишком маленьким и будет ok. А вот когда вычислительный процесс требует много итераций, нужно на каждой получать сколь можно более точный результат. Или при сортировке больших массивов данных нужно сравнения ускорить, тогда можно и на хитрые трюки пойти, используя целочисленные сравнения - в книге Генри Уоррена, мл., "Алгоритмические трюки для программистов" этому целая глава посвящена. А в коммерческих программах найден вполне справедливый способ: по умолчанию ставят $\varepsilon$ с хорошим запасом, но у пользователя есть возможность уменьшить $\varepsilon$ в установках - в руководстве стоит предупредить об опасности, а далее на усмотрение пользователя. Если же нужна так называемая многократная точность, то там и алгоритмы, и структуры данных другие. Можно использовать готовые инструменты типа вольфрамовской "Математики". ТС явно не преследует таких целей - он на 800 строк кода жалуется, а программа, подобная Математике, будет сильно сложнее ;-)
Skeptic в сообщении #837374 писал(а):
Деление на 0 определяется на самом низком машинном уровне. Все системы программирования, начиная с машинного языка, могут (обязаны) воспринимать эту ситуацию и содержать необходимые средства индикации и обработки. Логичнее воспользоваться встроенной системой обработки сбойных ситуаций, чем программировать её заново - это более эффективно и профессионально.
Не всегда более эффективно и профессионально. Могут быть сюрпризы. В Википедии есть большая статья "Обработка исключений", там секция "Достоинства и недостатки". Кстати, там утверждается:
Цитата:
Такое состояние существенно ограничивает возможности использования исключений, например, в ОС UNIX и её клонах и под Windows, так как большинство системного ПО и низкоуровневых библиотек этих систем пишется на языке Си, не поддерживающем исключений.
Это так? Си не поддерживает обработку исключений? ;-)

BTW. Есть много профессиональных подходов к проблеме точных вычислений. Нпр., один из таких подходов изложен в книге У.Кулиш и др., "Достоверные вычисления. Базовые численные методы", Москва-Ижевск: "Регулярная и хаотическая динамика", 2005.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение17.03.2014, 18:52 
Заслуженный участник


15/05/05
3445
USA
bin в сообщении #837871 писал(а):
Это так? Си не поддерживает обработку исключений? ;-)
:-) Тем не менее я сталкивался с ситуацией на Solaris, когда исключение, выданное в системной библиотеке не ловится в try-catch пользователя. Программа просто завершается с coredump'ом.

-- Пн мар 17, 2014 10:20:26 --

bin в сообщении #837871 писал(а):
У.Кулиш и др., "Достоверные вычисления. Базовые численные методы", Москва-Ижевск: "Регулярная и хаотическая динамика", 2005.
Только что обратил внимание: почему-то в России перевели версию книги для Pascal-XSC, а не более позднюю книгу для C++.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение17.03.2014, 23:02 


09/05/10
122
Ростов-на-Дону
Skeptic в сообщении #837374 писал(а):
Деление на 0 определяется на самом низком машинном уровне.

Обработчик прерывания нужен калькулятору?

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 01:42 
Аватара пользователя


22/09/09

1907
Yuri Gendelman

(Оффтоп)

Yuri Gendelman в сообщении #837954 писал(а):
Только что обратил внимание: почему-то в России перевели версию книги для Pascal-XSC, а не более позднюю книгу для C++.
Вы правы - очень интересный факт! Видимо, не только я, но и другие читатели, переводчики и издатели видят, что идеи, изложенные на Паскале, понять гораздо проще, чем изложенные на C++, и поэтому Паскалю принадлежит будущее ;-)

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 08:28 


01/12/11

1047
bin в сообщении #837871 писал(а):
Skeptic в сообщении #837374 писал(а):
Деление на 0 определяется на самом низком машинном уровне. Все системы программирования, начиная с машинного языка, могут (обязаны) воспринимать эту ситуацию и содержать необходимые средства индикации и обработки. Логичнее воспользоваться встроенной системой обработки сбойных ситуаций, чем программировать её заново - это более эффективно и профессионально.
Не всегда более эффективно и профессионально. Могут быть сюрпризы. В Википедии есть большая статья "Обработка исключений", там секция "Достоинства и недостатки". Кстати, там утверждается:
Цитата:
Такое состояние существенно ограничивает возможности использования исключений, например, в ОС UNIX и её клонах и под Windows, так как большинство системного ПО и низкоуровневых библиотек этих систем пишется на языке Си, не поддерживающем исключений.
Это так? Си не поддерживает обработку исключений? ;-).

Посмотрите "Язык программирования Си. Москва.1988" http://www.helloworld.ru/texts/comp/lang/c/c5/index.htm Обратите внимание на год.:mrgreen:

При выполнении в машинных командах нет прерывания "деление на 0", а есть прерывание "переполнение". Это несколько широкое понятие. Поэтому использование аппаратных прерываний полностью исключает вопрос о минимальном значении $\varepsilon$.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 10:10 
Заслуженный участник
Аватара пользователя


19/12/10
1546

(EtCetera)

EtCetera в сообщении #837301 писал(а):
whitefox
whitefox в сообщении #836787 писал(а):
Имхо, достаточно (x == 0)
Смотря с какой стороны посмотреть. С точки зрения корректности программы $\text{---}$ достаточно. С точки зрения хорошего стиля кодирования лучше избегать неявного преобразования типов для констант, т.е. объявлять константы того типа, который подразумевается по логике работы программы. А именно: 0.0 $\text{---}$ double, 0.0f $\text{---}$ float, 0.0L $\text{---}$ long double, 0 $\text{---}$ int, 0L $\text{---}$ long и т.д. В данном случае число типа double сравнивается с константой, которую лучше объявить как константу типа double $\text{---}$ 0.0.
Не сочтите за придирки, мне на самом деле хочется разобраться — с чем связаны такие рекомендации.

Лучше в смысле переносимости?
То есть возможны компиляторы которые не выполняют на стадии компиляции неявное преобразование типа константы, а вставляют это преобразование в исполняемый код?
Будет ли такое поведение компилятора соответствовать стандарту?
Имхо, неявное преобразование типа входит в константное выражение, а константные выражения должны вычисляться на стадии компиляции.

А какие рекомендации относительно замены if(x == 0.0); на if(!x); при x имеющем тип double?

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 11:04 


09/05/10
122
Ростов-на-Дону

(Некоторые прерывания)

Изображение

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 12:56 
Аватара пользователя


22/09/09

1907
Skeptic в сообщении #838175 писал(а):
Посмотрите "Язык программирования Си. Москва.1988"
Укажите, пожалуйста, страницу. Специфика ОС Демос и примеры для СМ-4 очень сейчас актуальны? ;-)

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 22:36 
Заслуженный участник


02/08/11
6874

(deleted)

whitefox в сообщении #838194 писал(а):
рекомендации относительно замены if(x == 0.0); на if(!x); при x имеющем тип double?
А вы попробуйте для $x = 0.3$.

 Профиль  
                  
 
 Re: Вопросы по реализации калькулятора. Си.
Сообщение18.03.2014, 22:45 
Заслуженный участник


04/05/09
4582
warlock66613 в сообщении #838446 писал(а):
whitefox в сообщении #838194 писал(а):
рекомендации относительно замены if(x == 0.0); на if(!x); при x имеющем тип double?
А вы попробуйте для $x = 0.3$.
Вы полагаете будет разница?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 51 ]  На страницу Пред.  1, 2, 3, 4  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group