Конференция "Начинающим" » ЧИсла меньше машинного эпсилон
 
  • dmk © (01.05.18 04:03) [0]
    Всем привет!

    Подскажите пожалуйста, как сравнить такие числа, если тип числа double?

     DoubleEpsilon := 2.22044604925031e-16;  
     X := -9.30880643132136e+18;
     if Abs(X) < DoubleEpsilon then X := 0.0;



    Все, что меньше эпсилона вообще не воспринимается :(
  • dmk © (01.05.18 04:12) [1]
    Сравнение с NaN, NegInfinity, PosInfinity не помогает.
    Знаки сравнения на это число не реагируют.
  • kilkennycat © (01.05.18 10:33) [2]

    > если тип числа double

    сделать типом Extended


    > DoubleEpsilon := 2.22044604925031e-16;

    а если посмотреть, что получается после присваивания?
  • kilkennycat © (01.05.18 10:38) [3]
    а вообще, сравнение таких чисел делают с помощью SameValue, CompareValue, IsZero
  • dmk © (01.05.18 14:11) [4]
    DoubleEpsilon как раз еще воспринимается, а вот X := -9.30880643132136e+18 уже нет.
    Для Double это EFloatingOverflow. Проблема в том, что Exception не генерится.
    Получается при вычислении тангенса в некоторых случаях.
  • Sha © (01.05.18 17:37) [5]
    можно не допускать, чтобы при вычислениях числа становились слишком малыми, умножая их на некоторый коэффициент
  • KilkennyCat © (01.05.18 18:45) [6]
    а если использовать сторонний математический юнит?
  • Германн © (02.05.18 02:31) [7]

    > Все, что меньше эпсилона вообще не воспринимается

    А -9.30880643132136e+18 никак не меньше эпсилона.
  • Германн © (02.05.18 02:39) [8]
    Ну т.е. от слова совсем. :)
  • dmk © (02.05.18 13:59) [9]
    Германн ©   (02.05.18 02:31) [7]
    Я Abs использую.
  • Dimka Maslov © (02.05.18 21:04) [10]
    1. Убедиться, правомочно ли мы сравнивает минус 16-тую степень с плюс 18-той.
    2. Если нет, то можно, зная формат хранения вещественных чисел выдрать из них мантиссу и экспоненту, привести к одной степени и сравнивать уже их
  • KilkennyCat © (03.05.18 01:22) [11]

    > выдрать из них мантиссу и экспоненту

    а выдерится ли из результата, оказавшийся меньше эпсилонного?
    и кстати, а вообще, результат вычислений может быть меньше машинного эпсилона?
  • dmk © (03.05.18 03:01) [12]
    >и кстати, а вообще, результат вычислений может быть меньше машинного эпсилона?
    Да. И Exception не срабатывает. Срабатывает, когда пытаешься сложить 2 числа.
  • KSergey © (03.05.18 10:31) [13]
    > 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;
    >
    > Все, что меньше эпсилона вообще не воспринимается :(

    Поясните, пожалуйста, смысл термина "не воспринимается". Я его не понимаю.
    Что происходит в приведённом вами коде? и напишите что вы ожидали. Так будет понятнее
  • dmk © (03.05.18 12:21) [14]
    >KSergey ©   (03.05.18 10:31) [13]
    Вы невнимательно читаете.
    Получающееся число меньше машинного эпсилона. И не ноль и не NaN.
    Оно не ошибочно. Оно есть, но при сложении или вычитании генерируется исключение.

    >Double принимает диапазон от  2.23e-308 до 1.79e+308
    Это если основание 1.79. В моем случае основание -9.308......, а значит и диапазон другой.
    Это же плавающая точка :)
  • Dimka Maslov © (03.05.18 13:09) [15]

    > dmk ©   (03.05.18 12:21) [14]

    -9.30880643132136e+18 или же всё таки
    -9.30880643132136e-18;
  • KSergey © (03.05.18 13:16) [16]
    > 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;

    Теперь скажи, что я читаю невнимательно? и, главное, зачем ты про это пишешь?
  • dmk © (03.05.18 13:23) [17]
    >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
  • KSergey © (03.05.18 13:31) [18]
    > dmk ©   (03.05.18 13:23) [17]
    > -9.30880643132136e+18 = 0.00000000000000000930880643132136.
    >
    > Вроде так.

    В чего это вдруг??

    -9.30880643132136e+18 = -9308806431321360000
  • KSergey © (03.05.18 13:41) [19]
    > 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 нет.
 
Конференция "Начинающим" » ЧИсла меньше машинного эпсилон
Есть новые Нет новых   [118639   +35][b:0][p:0.001]