![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
рффшник |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
Я сам не программист, но для решения некоторых прикладных задач потребовалось изучить Си. И при решении одной из таких задач вылезла одна маленькая проблемка. Есть некоторая проверка истинности :
if ((выражение типа дабл)!=0){ нечто } но иногда выходит так, что выражение, которое должно быть равно нулю - равно некоторому очень маленькому числу, что приводит к ненужному выполнению условия (выражение типа дабл)!=0. Из-за этого программа работает не вполне корректно. Можно исправить проблему, если вместо проверки равенства сделать другую проверку: if (fabs(выражение типа дабл)>x) но встает вопрос, каким минимальным можно взять "х"? Эмпирически оно получается порядка 10^-14. Но у меня нет гарантий, что определенном стечении обтоятельств не потребуется, скажем, 10^-13. Как быть, господа программисты? ЗЫ если это важно: выражения типа дабл равно сумма квадратов n double чисел минус квадрат суммы n double чисел |
nik_vic |
![]()
Сообщение
#2
|
Активный участник ![]() ![]() ![]() Группа: Пользователи Braingames Сообщений: 753 Регистрация: 22.1.2008 Пользователь №: 6 125 ![]() |
Проблема стандартна и во всех языках решается одинаково - выбором этого х.
Конкретика зависит от задачи, иногда его выбирают как малую долю участвующих в сравнении значений. -------------------- Где это видано?
|
рффшник |
![]()
Сообщение
#3
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
Проблема стандартна и во всех языках решается одинаково - выбором этого х. Конкретика зависит от задачи, иногда его выбирают как малую долю участвующих в сравнении значений. это, конечно, логично. В моей задаче достаточно будет взять 10^-10, это будет в пределах статистической погрешности измеренных величин. Но можно ли быть уверенным, что эти необходимые мне 10^-10 будут хорошо согласовываться с машинными вычислениями?! Хотелось бы знать, разве не существует некого конкретного числа, выше которого погрешность при операциях с числами double не получится? возможно, это конкретное число будет зависеть от конктреной системы - хз. Хотя есть ведь стандарт ANSI, а в нем вроде все системно независимо. |
nik_vic |
![]()
Сообщение
#4
|
Активный участник ![]() ![]() ![]() Группа: Пользователи Braingames Сообщений: 753 Регистрация: 22.1.2008 Пользователь №: 6 125 ![]() |
Хотелось бы знать, разве не существует некого конкретного числа, выше которого погрешность при операциях с числами double не получится? Никак нет - сами числа могут получаться в процессах разной вычислительной сложности. И, совсем просто, если порядки двух чисел одинаковы (в точном смысле одинаковости соответствующих бит), то их разность может не иметь ни одной точной цифры. -------------------- Где это видано?
|
Mouse |
![]()
Сообщение
#5
|
![]() и.о. админа ![]() ![]() Группа: Администраторы Сообщений: 86 Регистрация: 5.12.2006 Пользователь №: 20 ![]() |
QUOTE Проблема стандартна и во всех языках решается одинаково - выбором этого х. проблемма в операциях с потерей данных. всё зависит от того с какими числами работаете, и сколько операций происходит(и какие они, не помню как называются но операции +- - плохие */ - хорошие) проблемма обычно возникает если числа несоразмерные т.е. отношение порядка длинны мантисы. т.е. 1е300+1е250-1е300=0(в С++) погрешности(относительная) операций типа +- = 1е-15*(разрядность_большего по_модулю-разрядность_меньшего_по_модулю)^10. т.е 1.???+1000.???? даст погрешность 1е-12 для сравнения положительных чисел типа сумма квадратов лучше использовать не обсолютную погрешность, а относительную. т.е. double m1=max(fabs(a),fabs( ![]() ![]() if(m2/m1>0.999999)то равны QUOTE Хотя есть ведь стандарт ANSI, а в нем вроде все системно независимо. типы в С++ системо зависиммы например long double в MS/Intel С++ это 8байт(15знаков мантиса), в Борланде 10(19знаков вроде), что странно т.к. 10байт это вроде родной для х86 тип. |
Geen |
![]()
Сообщение
#6
|
Участник ![]() ![]() Группа: Пользователи Braingames Сообщений: 52 Регистрация: 29.5.2007 Пользователь №: 1 027 ![]() |
Дисперсия неравна нулю, если есть различающиеся числа - проще сделать флаг, и во время цикла вычисления дисперсии сделать соответствующую обработку. Много времени она не займёт (по отношению к квадратам), зато будет именно то, что хочется.
|
рффшник |
![]()
Сообщение
#7
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
Mouse, спасибо!
Geen, о какой дисперсии и о каком флаге вы говорите? ниче не понял... |
waldian |
![]()
Сообщение
#8
|
![]() Активный участник ![]() ![]() ![]() Группа: Пользователи Braingames Сообщений: 813 Регистрация: 20.4.2007 Из: Питер Пользователь №: 103 ![]() |
Mouse, спасибо! Geen, о какой дисперсии и о каком флаге вы говорите? ниче не понял... Да просто выражение в написанном виде ни что иное как дисперсия набора из этих самых n чисел, а она равна 0 только если все числа равны. Только сравнивать даблы на равенство просто так тоже нельзя ![]() |
Geen |
![]()
Сообщение
#9
|
Участник ![]() ![]() Группа: Пользователи Braingames Сообщений: 52 Регистрация: 29.5.2007 Пользователь №: 1 027 ![]() |
|
рффшник |
![]()
Сообщение
#10
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
Да просто выражение в написанном виде ни что иное как дисперсия набора из этих самых n чисел, а она равна 0 только если все числа равны. ах, вон оно что. Не сразу врубился о чем речь. В том выражении не хватает домножения на n квадрата суммы. Тогда это будет не дисперсия, а знаменатель выражения для определения одного из коэффициентов уравнения прямой методом МНК ![]() а как даблы можно сравнивать? |
Mouse |
![]()
Сообщение
#11
|
![]() и.о. админа ![]() ![]() Группа: Администраторы Сообщений: 86 Регистрация: 5.12.2006 Пользователь №: 20 ![]() |
QUOTE Да просто выражение в написанном виде ни что иное как дисперсия набора из этих самых n чисел, а она равна 0 только если все числа равны. ввели в ступор. для дисперсии в выражении вроде ещё одного N нехватает иначе 1^2+1^2!=(1+1)^2 если дело в проверки дисперсия=0(все числа одинаковые) то правильно условие будет(max-min<"погрешность_приборов/компа") double сравнивать на = нельзя. это основы компьютерных вычислений(забыл как у нас этот раздел был). правила там достаточно просты. 0. = считаеться как попадание в область(т.е. |x-y|<погрешность), и чаше всего относительную(типа различие в 6м знаке, т.е что-то типа |x-y|/(|x|+|y|)<1e-6) 1. */ на погрешность почти не влияют 2. + на ответ мало влияет, 1000000001 и 1000000000 можно сказать равно 3. - можно ожидать что угодно, как я привёл пример 10^250 4. ну и так далее, нам этот курс несколько недель читали ![]() |
рффшник |
![]()
Сообщение
#12
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
double сравнивать на = нельзя. это основы компьютерных вычислений(забыл как у нас этот раздел был). правила там достаточно просты. 0. = считаеться как попадание в область(т.е. |x-y|<погрешность), и чаше всего относительную(типа различие в 6м знаке, т.е что-то типа |x-y|/(|x|+|y|)<1e-6) 1. */ на погрешность почти не влияют 2. + на ответ мало влияет, 1000000001 и 1000000000 можно сказать равно 3. - можно ожидать что угодно, как я привёл пример 10^250 4. ну и так далее, нам этот курс несколько недель читали ![]() Весело получается. Сегодня с утра я еще и не задумывался, что равно может быть на самом деле и не очень то равно ![]() Кстати, а вот эти слова: QUOTE погрешности(относительная) операций типа +- = 1е-15*(разрядность_большего по_модулю-разрядность_меньшего_по_модулю)^10. т.е 1.???+1000.???? даст погрешность 1е-12 означают, что А-В посчитается с погрешностью меньшей 1е-15, при 0<A,B<1? |
Mouse |
![]()
Сообщение
#13
|
![]() и.о. админа ![]() ![]() Группа: Администраторы Сообщений: 86 Регистрация: 5.12.2006 Пользователь №: 20 ![]() |
QUOTE означают, что А-В посчитается с погрешностью меньшей 1е-15, при 0<A,B<1? не меньшей, а сравнимой. т.е. ошибка будет где-то в 15м знаке после запятой, зависит от методов округления. берите 1е-14 при 0<A,B<1.(учитывайте что разрядность двоичная, т.е. гарантируемая точность операции это спецификация процессора/системы) QUOTE Сегодня с утра я еще и не задумывался, что равно может быть на самом деле и не очень то равно сравните состояние милиордеров по версии различных источников(в одинаковое время), по теории равны, по разнице, бюджет малой(а может и несовсем) страны ![]() |
рффшник |
![]()
Сообщение
#14
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
|
рффшник |
![]()
Сообщение
#15
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
Господа, еще один вопрос: у меня есть дабл и я хочу на него посмотреть. Как сделать так, чтобы он выводил не первые N значащих знаков, а округлял с точностью до нного знака?
|
Geen |
![]()
Сообщение
#16
|
Участник ![]() ![]() Группа: Пользователи Braingames Сообщений: 52 Регистрация: 29.5.2007 Пользователь №: 1 027 ![]() |
%.15g например
|
рффшник |
![]()
Сообщение
#17
|
Новичок ![]() Группа: Пользователи Braingames Сообщений: 15 Регистрация: 21.4.2007 Пользователь №: 137 ![]() |
|
![]() ![]() |
![]() |
Упрощённая версия | Сейчас: 10.7.2025, 4:21 |