Да как же вы не поймете(!!!!) — это функция ВЫВОДА, она выводит.
Если в 64 бита я могу запихать:
"3ff0000000000000" это 1
"3ff0000000000001" это 1.0000000000000002
N>Для Вас новость, что вычисления с плавающей точкой в принципе неточные? И что ни одно число, если оно не кратно степени двойки, не может быть представлено точно в каком-то из стандартных IEEE binary форматах? Тогда у Вас ещё очень много открытий. Вот, например, второй пример, которому учат в вузе на соответствующем курсе:
Блин —
Еще раз и последний
1) При делении, умножении и в "константе в ТЕКСТЕ программы" значенние ( пример ) 0.06 равно = 0.059999999999999998
Ощибка от 0.06 равна — 0.00000000000002
В формате это значение равно 0.06 = "3faeb851eb851eb8"
Если мы прибавим к нему минимально возможное тут значение — в последний разряд... там где eb8 будет не 8 (1000) а 9 ( 1001). То значение будет уже
"0.060000000000000005" или в формате = "3faeb851eb851eb9"
Разница от 0.06 больше и равна = 0.0000000000005
Следующее минимальное изменение дает уже 0.060000000000000012 это "3faeb851eb851eba"
Вот мы имеем проблему
2) Если мы НАПРИМЕР прибавим к 0.05 + 0.01 то мы НЕ получим ТО ЖЕ что и в варианте с умножением, делением и в константе в тексте(!!!). То есть мы получим "0.060000000000000005" или в формате = "3faeb851eb851eb9"
И в итоге мы имеем "проблему" — что в результате умножения мы получаем форму такуюже как в константе а в результате сложения мы получаем следуюющее значение.
Надо найти алгоритм ПРИВЕДЕНИЯ из результата сложения всегда к форме представления или к тому же результату что и в результате умножения.
3f847ae147ae147a — это 0.0099999999999999985
3f847ae147ae147b — это 0.01 (форма представления в языке )
3f847ae147ae147с — это 0.010000000000000002
N>Как вы думаете, какой ответ она напишет? 9.9? Нет, она напишет 10. Потому что внутри этот 10 является 9.9999999999999804600747665972448885440826416015625.
N>И вот там же на лекциях чётко говорят: хотите сравнивать числа на равенство, полученные из разных даже очень простых вычислений? Нет проблем, определите так называемый эпсилон для такого сравнения и проверяйте abs(_d3 — _d4) < epsilon. N>Чему этот epsilon будет равен в Вашем случае — не знаю. Но если Вы хотите двух цифр после запятой, он равен 0.005.
Уважаемый — вы гоните БАНАЛЬНОСТИ!! Да и к тому же ощибочные = эпсилон для дабла это
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
И означает оно то минмальное значение которое позволяет различить два числа равные ( почти ) единице.
Но не суть — проблема не в этом.
А>>Достал квт совсем.
N>Конечно, он "достанет", если, нифига в теме не зная и не представляя особенности, сунуться с заявлением "почините-ка это мне", считая, что это какие-то "ошибки представления". Нету тут ошибок представления, не надейтесь. Есть законно сделанные по всем правилам вычисления и есть естественные проблемы округлений при таких вычислениях. Не нравится — у Вас есть масса вариантов:
N>1. Применить вместо этого библиотеку работы с плавающей точкой с десятичными порядком и мантиссой. Это очень правильный метод, если задача — не из матфизики, а из финансов, бухгалтерии и т.д.
Мне на надо с целыми мне надо с даблами.
N>2. Применять округление вручную, как в прошлом моём ответе.
Какое округление еще.
N>3. Сравнивать через epsilon, как в этом сообщении. N>4. Уйти вообще от проблемы сравнения через замену алгоритма. N>5. Бросить всё и заплакать.
N>Выбирайте.
Вообщем, попробуйте представить, что вы сейчас говорите с человеком гораздо лучше вас разбирающемся в "проблеме", и исходя из этого понять что готовых ответов в области банальностей тут нет.
Это я говорю вам, чтобы вы вообще в принципе поменяли подход — вас спрашивают не школькники и студенты, а люди разбирающиеся лучше вас, и следовательно есть два варианта :
1)Думать, вместе, советоваться уточнять и прочее
2)Просто молчать. Если вас это не интересует.
))
Здравствуйте, Аноним, Вы писали:
А>Последнее сообщение ибо я не понимаю что мне тут могут помочь, если уровень низкий. А>Это я говорю вам, чтобы вы вообще в принципе поменяли подход — вас спрашивают не школькники и студенты, а люди разбирающиеся лучше вас, и следовательно есть два варианта :
Аноним, ты какой-то агрессивный. К тому же не попадаешь в ветку комментариев, порождая каждый раз новый топик.
А>Это я говорю вам, чтобы вы вообще в принципе поменяли подход — вас спрашивают не школькники и студенты, а люди разбирающиеся лучше вас
С чего вдруг? иногда тупят не только школьники. Непонимание матчасти именно у топикстартера.
еще раз: 0.1 + 0.1 не обязана равняться 0.2. от слова "вообще".
бывает хлеще. когда 0.1 + 0.1 не равна 0.1 + 0.1 :
и вдруг срабатывает ассерт. а может и не сработать (зависит от компилятора и его опций).
и ничего удивительного в этом нет.
никто никогда не обещал, что результаты вычислений будут совпадать. ВСЕ вычисления с плавучкой -- приближенные.
даже константное выражение в коде программы.
А>Да как же вы не поймете(!!!!) — это функция ВЫВОДА, она выводит.
Кто бы спорил
А>Если в 64 бита я могу запихать:
А>"3ff0000000000000" это 1 А>"3ff0000000000001" это 1.0000000000000002
Нет, в последнем случае это 1.0000000000000002220446049250313080847263336181640625. А 1.0000000000000002 это приближённое представление по принципу "ограничим самой старшей из цифр, которая меньше дискрета представления".
А>Блин — А>Еще раз и последний А>1) При делении, умножении и в "константе в ТЕКСТЕ программы" значенние ( пример ) 0.06 равно = 0.059999999999999998 А>Ощибка от 0.06 равна — 0.00000000000002
Да, именно так. И почему Вас это удивляет?
А>В формате это значение равно 0.06 = "3faeb851eb851eb8"
Да, оно "равно" 0.06, ибо, согласно C99 (пункт 7.19.6.1, параграф 8), '%g' выбирает формат или по %e (с явной печатью степени), или по %f (с фиксированной точкой), а, для %f, цитирую,
If the precision is missing, it is taken as 6
.
То есть если Вы выводили по умолчанию, оно использовалось как "%.6f". И далее общее правило для всех режимов (%f, %e, %g):
The value is rounded to the appropriate number of digits.
Ключевое слово — "rounded".
Или Вы опять будете настаивать на C++? Тогда, например, в C++11 final draft таблица в пункте 27.5.5.2 говорит про те же самые 6 цифр по умолчанию. Цитировать тут таблицу не буду, уж извините.
Почему я Вам и говорил: выберите, как именно Вы будете печатать его, потому что режим по умолчанию скрывает эти подробности, и различия в double в минимальном бите в нём не печатаются.
А>И в итоге мы имеем "проблему" — что в результате умножения мы получаем форму такуюже как в константе а в результате сложения мы получаем следуюющее значение.
Нет. Вы НЕ получаете "форму такую же как в константе". Вы получаете другую форму, которую не можете отличить из-за своего неумения или нежелания прочитать и осознать, что и как делает то средство, которое Вы применяете для получения десятичного представления.
А>Надо найти алгоритм ПРИВЕДЕНИЯ из результата сложения всегда к форме представления или к тому же результату что и в результате умножения.
То есть Вам нужно было округлить до сотых? Или до миллионных, чтобы представляющиеся одинаково значения и были равны между собой, даже если это представление теряет точность?
Ну тогда Вам флаг в руки и комбинация из frexp(), round() и ldexp() из <math.h> навстречу.
А>Уважаемый — вы гоните БАНАЛЬНОСТИ!! Да и к тому же ощибочные = эпсилон для дабла это А>#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */ А>И означает оно то минмальное значение которое позволяет различить два числа равные ( почти ) единице.
Это другой эпсилон. К сожалению, тут некоторое смешение терминов. Но тот, кто в теме, различает их с ходу. Увы, к Вам это сегодня неприменимо.
N>>1. Применить вместо этого библиотеку работы с плавающей точкой с десятичными порядком и мантиссой. Это очень правильный метод, если задача — не из матфизики, а из финансов, бухгалтерии и т.д. А>Мне на надо с целыми мне надо с даблами.
А это будет с плавающей точкой, а не с целыми. Ссылки Вам дали.
N>>2. Применять округление вручную, как в прошлом моём ответе. А>Какое округление еще.
Самое простое. Например, round(x*100)/100 округляет до 1/100. Вы знаете, до какого значения Вы можете округлить без потери существенной части значения?
А>Это я говорю вам, чтобы вы вообще в принципе поменяли подход — вас спрашивают не школькники и студенты, а люди разбирающиеся лучше вас,
"Люди, разбирающиеся лучше нас" не делают таких нелепейших ошибок и умеют внятно описывать проблему. Так что — урежьте осетра.
А>1)Думать, вместе, советоваться уточнять и прочее А>2)Просто молчать. Если вас это не интересует. А>))
А>Все — пока. В смысле доствидания.
Здравствуйте, Аноним, Вы писали:
N>>Чему этот epsilon будет равен в Вашем случае — не знаю. Но если Вы хотите двух цифр после запятой, он равен 0.005.
А>Уважаемый — вы гоните БАНАЛЬНОСТИ!! Да и к тому же ощибочные = эпсилон для дабла это
А>#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
Он не "банальности гонит", а неточно излагает.
На всякий случай, что бы не было недопонимания, ОБЫЧНО, при работе с даблами, оценивают не только сам результат,
но и его точность. То есть про два значения обычно известно, с какой точностью они получены, и, соответственно, могут ли быть одним и тем же значением, просто по разному вычисленным, или нет.
Если оценка даёт априорную абсолютную погрешность. то её можно задать просто числом, которое задаст полуширину диапазона, и обычно его обозначают как эпсилон.
Если есть априорная оценка относительной погрешности, то задавать диапазон надо чуть хитрее.
Но, в любом случае, при нормальных вычислениях стараются делать так, что бы до DBL_EPSILON дело не доходило...
А>Но не суть — проблема не в этом.
Я не читал основную ветку внимательно, но так и не понял, что конкретно тебе надо. Суть проблемы ускользнула от меня...
Если таки хочешь помощи -- поясни конкретно что тебе надо.
И да, выражение (0.05 + 0.01)-(0.6 / 10.) нулю равно быть не обязано...
Дабловые нули они такие
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском