Smallest positive number x, such that x + 1.0 is not equal to 1.0.
- наименьшее положительное число, такое, что добавление к нему 1.0 изменяет значение числа. Иначе говоря, это относительная погрешность представления числа. То есть для 16 эта граница будет содержать столько-то десятичных девяток, а для 64 в конце будет отличие от 1 в 4 раза больше, для 8 в два раза меньше. Так что для ускорения округления с максимально возможной точностью придется эту точность вычислять. Вряд ли эти вычисления произойдут быстрее, чем исполнение штатных функций округления. Поскольку MQL не дает возможности работать прямо с адресами чисел, то брать в числе биты порядка не удастся, нужно будет придумывать аналог функции log по основанию 2. Она вряд ли будет работать быстро.
В следующей таблице представлены ограничения на значения констант с плавающей запятой. Эти ограничения также заданы в стандартном файле заголовка FLOAT.H. Ограничения на константы с плавающей запятой КонстантаЗначениеЗначение Количество цифр q, при котором число с плавающей запятой с q десятичными цифрами можно округлить в представление с...
Получается, что любое математическое действие вносит дополнительную погрешность, которая может быть как в плюс, так и в минус. Поэтому в общем случае, как подметил Vladimir, требуется нормализовывать полученный результат.
ceil(), floor() повторить вряд ли удастся, т.к. из мкл нельзя управлять режимом округления FPU. Единственное, наверное, что будет работать более менее адекватно - round() и то не точно по стандарту. Кстати, примерно так выглядит Си-шная round():
doubleround(double x)
{
fenv_t save_env;
feholdexcept(&save_env);
double result = rint(x);
if (fetestexcept(FE_INEXACT)) {
fesetround(FE_TOWARDZERO);
result = rint(copysign(0.5 + fabs(x), x));
}
feupdateenv(&save_env);
return result;
}
для понимания того что вы тут хотите округлять, нужно знать как именно и что теряется при переводе формата DOUBLE в формат INT. в данном случае вы получаете только целую его часть, которая остается после урезания. как следствие любое число с любым количеством знаков после запятой и любыми цифрами после запятой будут удалены и останется только целая часть. пример:
Andrey Kisselyov: для понимания того что вы тут хотите округлять, нужно знать как именно и что теряется при переводе формата DOUBLE в формат INT. в данном случае вы получаете только целую его часть, которая остается после урезания. как следствие любое число с любым количеством знаков после запятой и любыми цифрами после запятой будут удалены и останется только целая часть. пример:это называется потеря точности при изменении формата числа. как следствие
Получается, что любое математическое действие вносит дополнительную погрешность, которая может быть как в плюс, так и в минус. Поэтому в общем случае, как подметил Vladimir, требуется нормализовывать полученный результат.
pavlick_:
ceil(), floor() повторить вряд ли удастся, т.к. из мкл нельзя управлять режимом округления FPU. Единственное, наверное, что будет работать более менее адекватно - round() и то не точно по стандарту. Кстати, примерно так выглядит Си-шная round():
Конечно вы правы. Но я повторюсь. Для 99.9% задач абсолютно правомерна замена округляющих функций альтернативным более быстрым вариантом с применением преобразования дробных типов на (int) или (long). Опытный программист просто должен осознавать этот факт и применять его при целесообразности.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Так DBL_EPSILON - это и есть 16 знаков после запятой: 2.2204460492503131e-016
А в вашем случае получается фактически единица, т.к. разница составляет всего 1e-16, что в 2 раза меньше epsilon.
Работает с 0.9999999999999997, а с 0.9999999999999998 уже не работает.
Работает с 0.9999999999999997, а с 0.9999999999999998 уже не работает.
Вот еще прикол:
Число 2.2204460492503131e-016 в десятичной записи означает разрешающую способность формата double (https://msdn.microsoft.com/ru-ru/library/6bs3y5ya(v=vs.100).aspx), это
Smallest positive number x, such that x + 1.0 is not equal to 1.0.
- наименьшее положительное число, такое, что добавление к нему 1.0 изменяет значение числа. Иначе говоря, это относительная погрешность представления числа. То есть для 16 эта граница будет содержать столько-то десятичных девяток, а для 64 в конце будет отличие от 1 в 4 раза больше, для 8 в два раза меньше. Так что для ускорения округления с максимально возможной точностью придется эту точность вычислять. Вряд ли эти вычисления произойдут быстрее, чем исполнение штатных функций округления. Поскольку MQL не дает возможности работать прямо с адресами чисел, то брать в числе биты порядка не удастся, нужно будет придумывать аналог функции log по основанию 2. Она вряд ли будет работать быстро.
Вот еще прикол:
Получается, что любое математическое действие вносит дополнительную погрешность, которая может быть как в плюс, так и в минус. Поэтому в общем случае, как подметил Vladimir, требуется нормализовывать полученный результат.
ceil(), floor() повторить вряд ли удастся, т.к. из мкл нельзя управлять режимом округления FPU. Единственное, наверное, что будет работать более менее адекватно - round() и то не точно по стандарту. Кстати, примерно так выглядит Си-шная round():
пример:это называется потеря точности при изменении формата числа.
как следствие
с уважением.
для понимания того что вы тут хотите округлять, нужно знать как именно и что теряется при переводе формата DOUBLE в формат INT. в данном случае вы получаете только целую его часть, которая остается после урезания. как следствие любое число с любым количеством знаков после запятой и любыми цифрами после запятой будут удалены и останется только целая часть.
пример:это называется потеря точности при изменении формата числа.
как следствие
с уважением.
А зачем так сложно:
Чем такой вариант лучше более простого?:
Получается, что любое математическое действие вносит дополнительную погрешность, которая может быть как в плюс, так и в минус. Поэтому в общем случае, как подметил Vladimir, требуется нормализовывать полученный результат.
ceil(), floor() повторить вряд ли удастся, т.к. из мкл нельзя управлять режимом округления FPU. Единственное, наверное, что будет работать более менее адекватно - round() и то не точно по стандарту. Кстати, примерно так выглядит Си-шная round():
Конечно вы правы. Но я повторюсь. Для 99.9% задач абсолютно правомерна замена округляющих функций альтернативным более быстрым вариантом с применением преобразования дробных типов на (int) или (long). Опытный программист просто должен осознавать этот факт и применять его при целесообразности.
А зачем так сложно:
Чем такой вариант лучше более простого?:
можно и так попробовать.
Опытный программист просто должен осознавать этот факт и применять его при целесообразности.
он не то что должен, он обязан это знать.
P.S. ваша формула не верна для всего множества значений.с уважением.
посмотрите мою, я обновил роунд до короткой формулы, теперь список полон и полностью работоспособен, пользуйтесь.
P.S. ваша формула не верна для всего множества значений.
посмотрите мою, я обновил роунд до короткой формулы, теперь список полон и полностью работоспособен, пользуйтесь.см. выше
при x = 3 (любое целое число) происходит косячок :))