Странное поведение при сравнении SAS с цифрами c; вопрос точности? - PullRequest
1 голос
/ 15 января 2020

Я запускаю простой фильтр неравенств в SAS следующим образом:

data my_data;
    set my_data;
    my_var = sum(parent_var1, -parent_var2)
run;

proc sql;
    select my_var format=32.32
    from my_data
    where my_var < 0.02;
quit;

Я получаю следующий результат:

my_var
.0200000000000000000000000000000
.0200000000000000000000000000000
.0200000000000000000000000000000
(etc...)

Проблема, если она не очевидна, заключается в что мне нужны числа ниже .02, но они очень похожи на мое число равно .02.

В соответствии со свойствами, перечисленными при просмотре набора данных, длина my_var установлена ​​равной 8. parent_var1 и parent_var2 - оба десятичных числа, длина 8 и формат 8.5.

Может кто-нибудь объяснить, что здесь происходит? Есть ли где-то скрытая точность, которую я не вижу?

Ответы [ 2 ]

1 голос
/ 15 января 2020

SAS имеет только двоичный тип данных с плавающей запятой для чисел. Не существует типа, который вместо этого выполняет десятичную арифметику c. Таким образом, у вас может быть значение немного меньше 0,02.

Возможно, вы захотите округлить ваши значения до некоторого фиксированного числа десятичных разрядов, скажем, до четырех или пяти. Попробуйте этот код на своих данных и убедитесь, что вы все еще видите эти 0,02 значения.

data my_data;
   set my_data;
   my_var = round(sum(parent_var1, -parent_var2),0.00001) ;
   if my_var < 0.02 then put (my_var paren_var1 parent_var2) (= best32.8) ;
run;
0 голосов
/ 16 января 2020

Вы можете попытаться использовать функцию FUZZ , которая возвращает ближайшее целое число, если аргумент достаточно близок . Однако вам нужно умножить обе части выражения where на 100, чтобы оно работало должным образом.

proc sql;
    select my_var format=32.32
    from my_data
    where fuzz(my_var * 100) < 2;
quit;

Дополнительную информацию о том, почему это происходит с типами с плавающей точкой, вы можете найти в следующих статьях / презентациях:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...