|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Что float, что double, что decimal используют округления последнего знака. У меня есть задача. Есть отрезок с двумя концами, заданными double. Нужно разделить этот отрезок на n равных частей. С учётом округлений равные части никак не получатся. Т. е. если я буду прибавлять к координате начала исходного отрезка по одной части, пока не дойду до конца, то точно на конец могу и не попасть с точностью до последнего знака. Что делать? Говорят, можно задаться точностью поменьше, чем та, на которую рассчитано double, в результате округления станут беспокоить вас значительно меньше. Как эти округления распространить на весь проект? Ещё вопрос. Вот сделал я расчёты с округлениями. А если будет, например, вариант 9,999999999999999_9, где последняя девятка (после подчёркивания) при округлении всё равно будет влиять даже на самый первый разряд. Что делать? И вообще, как решать такие проблемы? Последний разряд всегда прыгает. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 13:34 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Насчёт округлений я имел ввиду, чтобы реальные расчёты были с максимальной точностью, но при присвоении переменным результатов вычислений всё округлялось до какого-то знака. В каждом месте во всём проекте вызывать округления и приведения - естественно не подойдёт. Это, я так понимаю, нужен какой-то свой тип чисел заводить? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 13:38 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
хехехе вычислительная математика, перед тем как применять методы вычислительной математики на практике стоило бы почитать о таких вещах как погрешность, алгебраическая погрешность. Что вы решаете? квадратура функции методом прямоугольников или золотое сечение? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 13:42 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Ну вообще decimal - это тип с высокой точностью Ключевое слово decimal обозначает 128-разрядный тип данных.По сравнению с типом данных с плавающей запятой, тип decimal имеет более точный и узкий диапазон, благодаря чему он походит для финансовых расчетов.В следующей таблице представлен приблизительный диапазон и точность для типа decimal. А делают обычно так, если хочется идеальной точности: смотри реализацию типа Money ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 13:46 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
user7320, ограниченность разрядной сетки это вечный бич, и общих методов решения данной проблемы не существует. почитайте про численные методы, похоже вы с ними не знакомы , т.к. такой вопрос задаёте. что такое численные методы , в чём их особенность при решении на ЭВМ. без этого про округления трудно говорить. можно подсказать один полууниверсальный метод. умножить но большое целое, и работать с BigInteger. при таком подходе точность можно варировать. ценой уменьшения скорости вычислений. таки да, что вы там творите. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 13:48 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Да проблема не в точности. Мне даблов за глаза хватает. Мне вообще достаточно трёх знаков после запятой. Просто с даблами удобнее работать, чем с флоатами - бОльшая часть всех операций во встроенном классе Math возвращает даблы или принимает их. Флоаты тоже есть, конечно, но даблы чаще. Я не понмю точно, почему я выбрал именно даблы. Вначале на флоатах делал, но потом задолбался переводить из одного в другое и решил, что ну его нафиг и пусть везде, где не целые числа, будут даблы. Но проблема не в точности. Проблема, как тут сказали, в ограниченности разрядной сетки. А если точнее, в том, что последний разряд всегда округляется. Я описал проблему: есть отрезок, надо поделить его на произвольное количество одинаковых частей. При таком делении в общем случае получаются отрезки с длиной, выражающейся числом разрядов, превышающей точность дабла. Тогда идёт округление последнего разряда в дабле. Потом я использую это округлённое число в качестве инкремента: от начала первоначального целого отрезка иду до его конца. Естественно, на конце получается, что координаты не совпадают где-то в последнем разряде. А могут и в предпоследнем. Разница, вобщем, малюсенькая, но если проверка идёт на строгое равенство, то она не проходит. НО ПО СУТИ-ТО ДОЛЖНА ПРОХОДИТЬ. Для себя пока решил, что буду как-то по другому делать. Т. е. либо нильзя полученное значение от деления использовать в качестве инкремента, либо сравнение проводить не строгое, а в пределах какого-то допустимого интервала, чтобы погрешность округления обойти. Но это костыль, блин... Про численные методы почитаю, спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 22:34 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
user7320Разница, вобщем, малюсенькая, но если проверка идёт на строгое равенство, то она не проходит. НО ПО СУТИ-ТО ДОЛЖНА ПРОХОДИТЬ. садись, два. плавающие на равенство сравнивать нельзя. Критерий равенства плавающих только один: abs(x-y) < epsilon ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 22:38 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
user7320Про численные методы почитаю, спасибо. сначала прочитай, а потом про костыли говори ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 22:39 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
double на x64 более оптимизирован, вледствие - быстрей, чем float. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2012, 22:54 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Не, это, конечно, круто, когда ты и "численные методы", и ещё всякую кучу знаний знаешь, но на практике часто бывает, что проходить классический курс некогда, а надо за ночь накодить что-то приемлемое (вот как щас). Для себя решил, что тут к каждой конкретной проблеме свой подход нужен. Ну нет у меня вычислений, где бы к каждому значению его погрешность бы ещё тянулась. Итак код медленно выполняется, так ещё с погрешностями работать... Я просто посмотрел, что данные различаются уже в третьем знаке после запятой. В принципе, характер данных таков, что два соседних совпадут с точностью до пятнадцатого знака в одном случае из триллионов триллионов. Поэтому просто взял и обрезал критическое значение до восьмого знака. У меня там проверка на "больше" идёт, ну так когда обрезаешь, то получается всегда меньше. Фундаментальная подготовка - это, конечно, хорошо. Только все фундаменталисты в яндексах да гуглах работают (и то не факт)... а за ночь в задрищенском институте студент на четверть ставки должен "ещё вчера" сделать расчёт. Ща ещё гляну, где там критические сравнения и тоже своего рода "оптимизирую". Только если потом кто разобьётся, или что-то взорвётся, или скорая не успеет - я не виноват. Потом почитаю про "численные методы". ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 00:28 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
user7320, вы отказывайтесь нас понимать, тогда зачем вы тут пишите? на ПК любые вычисления с плавающей запятой не могут быть точными. Погрешность существует всегда, хотите вы этого или нет. Округление до последнего символа будет ВСЕГДА. Что бы вы не делали и как не старались. И чем больше вычислений вы производите над числом с плавающей точкой тем сильнее эта накапливаемая погрешность, именно по этому как тут и сказали при работе с плавающей точкой использовать равенства не возможно. Более того, для каждого мат. метода существует формула по которой считается погрешность каждого метода которую нужно не забыть указать в конечных результатах. мне не совсем понятно, зачем вы складывайте отрезки, нужно взять большой отрезок и разбить его на n частей. Вы так и не описали, что вы считаете, а экстрасенсов тут нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 10:03 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
user7320проходить классический курс некогда тогда слушайте внимательно тех, кто прошёл классический курс ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 11:06 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
МСУdouble на x64 более оптимизирован, вледствие - быстрей, чем float. Кому интересно: http://codearticles.ru/Home/ArticleView/2149 ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 11:07 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Roman Mejtesuser7320, вы отказывайтесь нас понимать, тогда зачем вы тут пишите? на ПК любые вычисления с плавающей запятой не могут быть точными. Погрешность существует всегда, хотите вы этого или нет. Округление до последнего символа будет ВСЕГДА. Что бы вы не делали и как не старались. И чем больше вычислений вы производите над числом с плавающей точкой тем сильнее эта накапливаемая погрешность, именно по этому как тут и сказали при работе с плавающей точкой использовать равенства не возможно. Более того, для каждого мат. метода существует формула по которой считается погрешность каждого метода которую нужно не забыть указать в конечных результатах. мне не совсем понятно, зачем вы складывайте отрезки, нужно взять большой отрезок и разбить его на n частей. Вы так и не описали, что вы считаете, а экстрасенсов тут нет. Ну, я отрезок в качестве примера привёл. Считаю я, например, осреднения. Т. е. есть несколько реализаций процесса (некая функция от аргумента) в примерно одних пределах по аргументу. Мне нужно найти среднюю реализацию этого процесса. Я нахожу минимум из всех максимумов и максимум из всех минимумов (банальное пересечение множеств реализаций) по аргументу - это и есть тот самый исходный отрезок. Потом делю получившийся отрезок на произвольно заданное число частей и получаю множество значений аргумента на осреднении. Теперь нужно найти соответствующее множество значений функции. Поскольку данные у меня дискретны, то значения аргумента на осреднении в общем случае не совпадают со значениями аргумента на каждой реализации. Тогда для каждого значения аргумента из осреднения ищу два ближайших значения аргумента из каждой реализации и вычисляю линейно интерполированное значение. Беру среднеарифметическое полученных интерполяций для каждого значения аргумента из осреднения - вот и получилось наше осреднение. Если вы в теме, то должны понять, я думаю - операция достаточно тривиальная. Но, как я её делаю! Я загоняю всё в цикл, где стартовое значение - начало неподелённого отрезка значений аргумента из осреднения, инкремент - результат деления этого отрезка на заданное число частей, а проверка окончания цикла - результат приращения стартового значения равен концу исходного отрезка. Понятно, что накопленная таким образом ошибка может привести к тому, что равенства никогда не будет. Даже если проверяь на "больше или равно". Поэтому я реализовал фактически то, о чём говорили и что я прочитал в Интернете - ввёл своего рода некий диапазон, в пределах которого числа с плавающей запятой у меня признаются равными. Я посморел, что у меня смежные в массиве данные практически не могут быть совпадающими с точностью до третьего знака после запятой. Тогда ввёл округление этих данных до восьмого знака - т. е. с огромным запасом. Точнее, я ввёл у себя в программе понятие верхнего и нижнего предела значения, в дополнение к самому значению - это и есть некий интервал погрешности. Эти пределы отличаются как раз в восьмом знаке. Реально вычисленное значение различается только в 14-ом-16-ом знаках, так что у меня огромный запас и тут. Но только ввёл я эти погрешности не по всем расчётам (мне везде это и не надо - программа вообще выводит с точностью до третьего знака), а где есть проверки на строгое равенство или неравенство (равно, не равно, больше, меньше). Вводить везде - слишком жирно и накладно по времени расчёта. Таких мест у меня относительно немного, так что должно сработать. Пока, собственно, и работает. А то, что я сверху написал, это о том, я мне некогда сейчас изучать всю теорию вычислительной математики, когда "должно быть сделано ещё вчера" (причём не помоей вине должно быть - это хотелка боссов). Я схватил основную идею и применил её в наиболее критических местах. Примерно так. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 11:27 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
авторНо, как я её делаю! Я загоняю всё в цикл, где стартовое значение - начало неподелённого отрезка значений аргумента из осреднения, инкремент - результат деления этого отрезка на заданное число частей, а проверка окончания цикла - результат приращения стартового значения равен концу исходного отрезка. Понятно, что накопленная таким образом ошибка может привести к тому, что равенства никогда не будет. Даже если проверяь на "больше или равно". Кстати, из этого описания должно быть понятно, что критическая часть тут - именно проверка условия окончания цикла. Промежуточные расхождения аргумента, даже если они там в последнем разряде неточны, скроются интерполяциями, тем более, что конечный результат важен с точностью до третьего знака или меньше. А вот когда условие окончания поставлено как строгое равенство-неравенство, тогда приплыли. Вот для условия окончания я и ввёл свои погрешности. Не для всех величин вообще, а именно для условия окончания цикла. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 11:31 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
user7320Поэтому я реализовал фактически то, о чём говорили и что я прочитал в Интернете - ввёл своего рода некий диапазон, в пределах которого числа с плавающей запятой у меня признаются равными. Я посморел, что у меня смежные в массиве данные практически не могут быть совпадающими с точностью до третьего знака после запятой. Тогда ввёл округление этих данных до восьмого знака - т. е. с огромным запасом. Точнее, я ввёл у себя в программе понятие верхнего и нижнего предела значения, в дополнение к самому значению - это и есть некий интервал погрешности. Эти пределы отличаются как раз в восьмом знаке. Реально вычисленное значение различается только в 14-ом-16-ом знаках, так что у меня огромный запас и тут. вы знаете про Epsilon ? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2012, 11:34 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
МСУdouble на x64 более оптимизирован, Не считая того, что строго наоборот... МСУвледствие - быстрей, чем float....это правда. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 00:51 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
sphinx_mvМСУdouble на x64 более оптимизирован, Не считая того, что строго наоборот... МСУвледствие - быстрей, чем float....это правда. x87 FPU is deprecated on x64, and in general SSE2 will be used for florating point. вуаля ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 01:07 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Изопропилsphinx_mvпропущено... Не считая того, что строго наоборот... пропущено... ...это правда. x87 FPU is deprecated on x64, and in general SSE2 will be used for florating point. вуаляИ что? Использование на 64-разрядной системе набор команд, ориентированных на 32-разрядные процессора, надо ограничивать - это в принципе нормально... А тип данных double, который используется для представления 64-разрядных значений с плавающей запятой, описан в IEEE-754 еще в середине 1980-х, продолжает быть описан в ревизии этого стандарта от 2008 года и никакого отношения ни к разрядности процессора, ни к используемому расширению для вычислений с плавающей запятой, ни, тем более, к разрядности программной среды не имеет... ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 02:06 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
sphinx_mv, какова связь режима 32/64 и сккорости работы SSE? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 09:24 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
sphinx_mvНе считая того, что строго наоборот... Не считая того, что так и нет аргументов. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 09:38 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 09:46 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Резюмация? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 10:02 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
Изопропилsphinx_mv, какова связь режима 32/64 и сккорости работы SSE? А какая связь Вашего вопроса с "double on x86" vs. "double on x64"? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 11:43 |
|
Проблема с округлениями в расчётах
|
|||
---|---|---|---|
#18+
МСУsphinx_mvНе считая того, что строго наоборот... Не считая того, что так и нет аргументов.А что тут дополнительно аргументировать?! Незачет, пересдача через месяц - и все! Это - элементарные базовые знания, отсутствие которых у Вас несомненно. Ваша заява ("double на x64 более оптимизирован") - это ОЧЕНЬ "сильно"... Хотелось бы посмотреть на эту Вашу "оптимизацию" структуры из 8 последовательных байт - и специально для x64... Аха... В-общем, читайте доки - они рулез: для обработки таких данных используются наборы оптимизированных инструкций (и ресурсов) процессора, а не "оптимизация структур". ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2012, 12:16 |
|
|
start [/forum/topic.php?fid=20&msg=38091605&tid=1405431]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
68ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
2ms |
others: | 320ms |
total: | 493ms |
0 / 0 |