-
Всем привет!
Подскажите пожалуйста, как сравнить такие числа, если тип числа double?
DoubleEpsilon := 2.22044604925031e-16;
X := -9.30880643132136e+18;
if Abs(X) < DoubleEpsilon then X := 0.0;
Все, что меньше эпсилона вообще не воспринимается :(
-
Сравнение с NaN, NegInfinity, PosInfinity не помогает.
Знаки сравнения на это число не реагируют.
-
> если тип числа double
сделать типом Extended
> DoubleEpsilon := 2.22044604925031e-16;
а если посмотреть, что получается после присваивания?
-
а вообще, сравнение таких чисел делают с помощью SameValue, CompareValue, IsZero
-
DoubleEpsilon как раз еще воспринимается, а вот X := -9.30880643132136e+18 уже нет.
Для Double это EFloatingOverflow. Проблема в том, что Exception не генерится.
Получается при вычислении тангенса в некоторых случаях.
-
можно не допускать, чтобы при вычислениях числа становились слишком малыми, умножая их на некоторый коэффициент
-
а если использовать сторонний математический юнит?
-
> Все, что меньше эпсилона вообще не воспринимается
А -9.30880643132136e+18 никак не меньше эпсилона.
-
Ну т.е. от слова совсем. :)
-
Германн © (02.05.18 02:31) [7]
Я Abs использую.
-
1. Убедиться, правомочно ли мы сравнивает минус 16-тую степень с плюс 18-той.
2. Если нет, то можно, зная формат хранения вещественных чисел выдрать из них мантиссу и экспоненту, привести к одной степени и сравнивать уже их
-
> выдрать из них мантиссу и экспоненту
а выдерится ли из результата, оказавшийся меньше эпсилонного?
и кстати, а вообще, результат вычислений может быть меньше машинного эпсилона?
-
>и кстати, а вообще, результат вычислений может быть меньше машинного эпсилона?
Да. И Exception не срабатывает. Срабатывает, когда пытаешься сложить 2 числа.
-
> dmk © (01.05.18 14:11) [4]
> DoubleEpsilon как раз еще воспринимается, а вот X := -9.30880643132136e+18 уже нет.
> Для Double это EFloatingOverflow. Проблема в том, что Exception не генерится.
Вот это не понял. Могли бы пояснить?
Double принимает диапазон от 2.23e-308 до 1.79e+308
У вас всего +18 степень. В чем беда?
> DoubleEpsilon := 2.22044604925031e-16;
> X := -9.30880643132136e+18;
> if Abs(X) < DoubleEpsilon then X := 0.0;
>
> Все, что меньше эпсилона вообще не воспринимается :(
Поясните, пожалуйста, смысл термина "не воспринимается". Я его не понимаю.
Что происходит в приведённом вами коде? и напишите что вы ожидали. Так будет понятнее
-
>KSergey © (03.05.18 10:31) [13]
Вы невнимательно читаете.
Получающееся число меньше машинного эпсилона. И не ноль и не NaN.
Оно не ошибочно. Оно есть, но при сложении или вычитании генерируется исключение.
>Double принимает диапазон от 2.23e-308 до 1.79e+308
Это если основание 1.79. В моем случае основание -9.308......, а значит и диапазон другой.
Это же плавающая точка :)
-
> dmk © (03.05.18 12:21) [14]
-9.30880643132136e+18 или же всё таки
-9.30880643132136e-18;
-
> dmk © (03.05.18 12:21) [14]
> >KSergey © (03.05.18 10:31) [13]
> Вы невнимательно читаете.
Чувак, я читаю внимательно.
Тебе ответ нужен или разборки кто внимательно или не внимательно читает?
Ты написал вот что:
> dmk © (01.05.18 04:03)
> DoubleEpsilon := 2.22044604925031e-16;
> X := -9.30880643132136e+18;
Теперь скажи, что я читаю невнимательно? и, главное, зачем ты про это пишешь?
-
>Dimka Maslov © (03.05.18 13:09) [15]
>-9.30880643132136e+18 или же всё таки
>-9.30880643132136e-18;
-9.30880643132136e+18 = 0.00000000000000000930880643132136.
Вроде так.
>KSergey © (03.05.18 13:16) [16]
Значит не понимаете о чем речь.
X := Tan(X)
E := DoubleEpsilon;
X = 0.00000000000000000930880643132136;
E = 0.000000000000000222044604925031;
//1.0 + X = Exception
//1.0 + E = No Exception
-
> dmk © (03.05.18 13:23) [17]
> -9.30880643132136e+18 = 0.00000000000000000930880643132136.
>
> Вроде так.
В чего это вдруг??
-9.30880643132136e+18 = -9308806431321360000
-
> dmk © (03.05.18 13:23) [17]
> X := Tan(X)
> E := DoubleEpsilon;
>
> X = 0.00000000000000000930880643132136;
> E = 0.000000000000000222044604925031;
>
> //1.0 + X = Exception
> //1.0 + E = No Exception
Чета неправда.
Или вопрос опций компилятора.
Вот программа, только что скомпилировал, запустил:
var X, E: Double;
var z: Double;
begin
X := 0.00000000000000000930880643132136;
E := 0.000000000000000222044604925031;
z := 1.0 + X;
writeln(z);
end.
Выдаёт:
1.00000000000000E+0000
Никаких Exception нет.