IPB

Добро пожаловать, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> Double в Си, нужна помощь
рффшник
7.2.2008, 14:24
Сообщение #1


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



Я сам не программист, но для решения некоторых прикладных задач потребовалось изучить Си. И при решении одной из таких задач вылезла одна маленькая проблемка. Есть некоторая проверка истинности :

if ((выражение типа дабл)!=0){
нечто
}

но иногда выходит так, что выражение, которое должно быть равно нулю - равно некоторому очень маленькому числу, что приводит к ненужному выполнению условия (выражение типа дабл)!=0. Из-за этого программа работает не вполне корректно. Можно исправить проблему, если вместо проверки равенства сделать другую проверку:

if (fabs(выражение типа дабл)>x)

но встает вопрос, каким минимальным можно взять "х"? Эмпирически оно получается порядка 10^-14. Но у меня нет гарантий, что определенном стечении обтоятельств не потребуется, скажем, 10^-13.

Как быть, господа программисты?

ЗЫ если это важно: выражения типа дабл равно сумма квадратов n double чисел минус квадрат суммы n double чисел

Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
nik_vic
7.2.2008, 15:08
Сообщение #2


Активный участник
***

Группа: Пользователи Braingames
Сообщений: 753
Регистрация: 22.1.2008
Пользователь №: 6 125



Проблема стандартна и во всех языках решается одинаково - выбором этого х.
Конкретика зависит от задачи, иногда его выбирают как малую долю участвующих в сравнении значений.


--------------------
Где это видано?
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
7.2.2008, 16:24
Сообщение #3


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



QUOTE(nik_vic @ 7.2.2008, 15:08) *

Проблема стандартна и во всех языках решается одинаково - выбором этого х.
Конкретика зависит от задачи, иногда его выбирают как малую долю участвующих в сравнении значений.


это, конечно, логично. В моей задаче достаточно будет взять 10^-10, это будет в пределах статистической погрешности измеренных величин. Но можно ли быть уверенным, что эти необходимые мне 10^-10 будут хорошо согласовываться с машинными вычислениями?! Хотелось бы знать, разве не существует некого конкретного числа, выше которого погрешность при операциях с числами double не получится? возможно, это конкретное число будет зависеть от конктреной системы - хз. Хотя есть ведь стандарт ANSI, а в нем вроде все системно независимо.
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
nik_vic
7.2.2008, 17:19
Сообщение #4


Активный участник
***

Группа: Пользователи Braingames
Сообщений: 753
Регистрация: 22.1.2008
Пользователь №: 6 125



QUOTE(рффшник @ 7.2.2008, 16:24) *

Хотелось бы знать, разве не существует некого конкретного числа, выше которого погрешность при операциях с числами double не получится?

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



--------------------
Где это видано?
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Mouse
7.2.2008, 17:38
Сообщение #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(cool.gif),m2=min(fabs(a),fabs(cool.gif);
if(m2/m1>0.999999)то равны

QUOTE
Хотя есть ведь стандарт ANSI, а в нем вроде все системно независимо.

типы в С++ системо зависиммы
например long double в MS/Intel С++ это 8байт(15знаков мантиса), в Борланде 10(19знаков вроде), что странно т.к. 10байт это вроде родной для х86 тип.
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Geen
7.2.2008, 17:58
Сообщение #6


Участник
**

Группа: Пользователи Braingames
Сообщений: 52
Регистрация: 29.5.2007
Пользователь №: 1 027



Дисперсия неравна нулю, если есть различающиеся числа - проще сделать флаг, и во время цикла вычисления дисперсии сделать соответствующую обработку. Много времени она не займёт (по отношению к квадратам), зато будет именно то, что хочется.
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
7.2.2008, 19:38
Сообщение #7


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



Mouse, спасибо!

Geen, о какой дисперсии и о каком флаге вы говорите? ниче не понял...
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
waldian
7.2.2008, 20:20
Сообщение #8


Активный участник
***

Группа: Пользователи Braingames
Сообщений: 813
Регистрация: 20.4.2007
Из: Питер
Пользователь №: 103



QUOTE(рффшник @ 7.2.2008, 19:38) *
Mouse, спасибо!

Geen, о какой дисперсии и о каком флаге вы говорите? ниче не понял...

Да просто выражение в написанном виде ни что иное как дисперсия набора из этих самых n чисел, а она равна 0 только если все числа равны.
Только сравнивать даблы на равенство просто так тоже нельзя smile.gif)
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Geen
7.2.2008, 22:20
Сообщение #9


Участник
**

Группа: Пользователи Braingames
Сообщений: 52
Регистрация: 29.5.2007
Пользователь №: 1 027



QUOTE(waldian @ 7.2.2008, 20:20) *

Да просто выражение в написанном виде ни что иное как дисперсия набора из этих самых n чисел, а она равна 0 только если все числа равны.
Только сравнивать даблы на равенство просто так тоже нельзя smile.gif)

Зато ошибка не накапливается smile.gif
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
7.2.2008, 23:14
Сообщение #10


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



QUOTE(waldian @ 7.2.2008, 20:20) *

Да просто выражение в написанном виде ни что иное как дисперсия набора из этих самых n чисел, а она равна 0 только если все числа равны.



ах, вон оно что. Не сразу врубился о чем речь. В том выражении не хватает домножения на n квадрата суммы. Тогда это будет не дисперсия, а знаменатель выражения для определения одного из коэффициентов уравнения прямой методом МНКsmile.gif


а как даблы можно сравнивать?
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Mouse
7.2.2008, 23:26
Сообщение #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. ну и так далее, нам этот курс несколько недель читали smile.gif
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
7.2.2008, 23:44
Сообщение #12


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



QUOTE(Mouse @ 7.2.2008, 23:26) *

double сравнивать на = нельзя. это основы компьютерных вычислений(забыл как у нас этот раздел был). правила там достаточно просты.
0. = считаеться как попадание в область(т.е. |x-y|<погрешность), и чаше всего относительную(типа различие в 6м знаке, т.е что-то типа |x-y|/(|x|+|y|)<1e-6)
1. */ на погрешность почти не влияют
2. + на ответ мало влияет, 1000000001 и 1000000000 можно сказать равно
3. - можно ожидать что угодно, как я привёл пример 10^250
4. ну и так далее, нам этот курс несколько недель читали smile.gif


Весело получается. Сегодня с утра я еще и не задумывался, что равно может быть на самом деле и не очень то равноsmile.gif

Кстати, а вот эти слова:

QUOTE
погрешности(относительная) операций типа +- = 1е-15*(разрядность_большего по_модулю-разрядность_меньшего_по_модулю)^10. т.е 1.???+1000.???? даст погрешность 1е-12


означают, что А-В посчитается с погрешностью меньшей 1е-15, при 0<A,B<1?
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Mouse
8.2.2008, 0:22
Сообщение #13


и.о. админа
**

Группа: Администраторы
Сообщений: 86
Регистрация: 5.12.2006
Пользователь №: 20



QUOTE
означают, что А-В посчитается с погрешностью меньшей 1е-15, при 0<A,B<1?

не меньшей, а сравнимой. т.е. ошибка будет где-то в 15м знаке после запятой, зависит от методов округления. берите 1е-14 при 0<A,B<1.(учитывайте что разрядность двоичная, т.е. гарантируемая точность операции это спецификация процессора/системы)

QUOTE
Сегодня с утра я еще и не задумывался, что равно может быть на самом деле и не очень то равно

сравните состояние милиордеров по версии различных источников(в одинаковое время), по теории равны, по разнице, бюджет малой(а может и несовсем) страны smile.gif
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
8.2.2008, 0:45
Сообщение #14


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



QUOTE(Mouse @ 8.2.2008, 0:22) *


сравните состояние милиордеров по версии различных источников(в одинаковое время), по теории равны, по разнице, бюджет малой(а может и несовсем) страны smile.gif



самим этим миллиардерам, наверное, интересно наблюдать, с какой точностью другие считают их деньги biggrin.gif
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
8.2.2008, 9:21
Сообщение #15


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



Господа, еще один вопрос: у меня есть дабл и я хочу на него посмотреть. Как сделать так, чтобы он выводил не первые N значащих знаков, а округлял с точностью до нного знака?
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Geen
8.2.2008, 12:17
Сообщение #16


Участник
**

Группа: Пользователи Braingames
Сообщений: 52
Регистрация: 29.5.2007
Пользователь №: 1 027



%.15g например
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
рффшник
11.2.2008, 18:25
Сообщение #17


Новичок
*

Группа: Пользователи Braingames
Сообщений: 15
Регистрация: 21.4.2007
Пользователь №: 137



QUOTE(Geen @ 8.2.2008, 12:17) *

%.15g например


ty!
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0 -

 



- Упрощённая версия Сейчас: 17.9.2021, 1:45
Яндекс.Метрика