2016-01-25 2 views
2

Рассмотрим следующую программу и вывод:Почему в двоичном формате. формат отличается от ширины 58?

data _null_; 
input a; 
length b $64; 
do i = 1 to 64; 
    fmtname = cats('binary',i); 
    b = cats(putn(a,fmtname)); 
    put i= b=; 
end; 
cards; 
1 
; 
run; 

Output (SAS 9.1.3, Windows 7 x64):

i=1 b=1 
i=2 b=01 
i=3 b=001 
i=4 b=0001 
i=5 b=00001 
/*Skipped a few very similar lines*/ 
i=58 b=0000000000000000000000000000000000000000000000000000000001 
i=59 b=11111110000000000000000000000000000000000000000000000000000 
i=60 b=111111110000000000000000000000000000000000000000000000000000 
i=61 b=1111111110000000000000000000000000000000000000000000000000000 
i=62 b=11111111110000000000000000000000000000000000000000000000000000 
i=63 b=011111111110000000000000000000000000000000000000000000000000000 
i=64 b=0011111111110000000000000000000000000000000000000000000000000000 

Последние несколько строк вывода из SAS 9.4 на Linux x64:

i=60 b=000000000000000000000000000000000000000000000000000000000001 
i=61 b=1111111110000000000000000000000000000000000000000000000000000 
i=62 b=11111111110000000000000000000000000000000000000000000000000000 
i=63 b=011111111110000000000000000000000000000000000000000000000000000 
i=64 b=0011111111110000000000000000000000000000000000000000000000000000 

Такое поведение довольно неожиданно для меня, по крайней мере, и, похоже, не документировано на help page. Это согласуется с документом, который я нашел here для ширины 64 - стандартная двойная точность - но я не понимаю, почему он переворачивается на ширину 59.

ответ

1

Я не совсем получаю тот же результат - минные выключатели на 61 - но Я считаю, что ответ тот же.

До некоторой точки - 58, 60, где-то там - SAS показывает вам целочисленное представление числа с фиксированной запятой. Проверьте это с десятичной, например, так:

data _null_; 
a=3.14159265358979323846264338327950288419716939937510582; 
length b $64; 
put a= hex4.; 
put a= hex8.; 
put a= hex16.; 
do i = 1 to 64; 
    fmtname = cats('binary',i); 
    b = cats(putn(a,fmtname)); 
    put i= b=; 
end; 
run; 

И вы получите своего рода-оф-удивительный результат - вы видите 000...0011 для большинства ваших строк, вплоть до 60. В документации не упоминает это, но он показывает это в примере (123.45 и 123 идентичны в binary8.).

Затем, начиная с 61 или 59 для вас, я предполагаю, что вы видите фактическое представление числа, поскольку SAS внутренне хранит его (или, возможно, как Intel внутренне хранит его).

Двоичный документация не объясняет это хорошо, но документация HEX. делает это объяснить довольно ясно в наконечнике:

Если ж < 16, HEXw. формат преобразует реальные двоичные числа в целые числа с фиксированной запятой, прежде чем записывать их как шестнадцатеричные символы. Он также записывает отрицательные числа в двухзначной нотации дополнений, а правая выровняет цифры. Если w равно 16, HEXw. отображает значения с плавающей запятой в их шестнадцатеричной форме.

Binary делает то же самое, и на моей машине это происходит прямо в точке, где HEX также произведет изменение - при 15x4 = 60. И HEX. показывает то же самое - уведомление ниже; hex4. и hex8. показать другой результат, чем hex16..

Чтобы быть ясным, значение, указанное на binary64., является правильным, а не любое усечение (хотя 61-63, а в вашем примере 59-60, усечены слева).


Я нашел SAS usage note по этому поводу, хотя это явно устарели на основе наших тестов:

Начиная с SAS® версии 7, BINARYw. формат был изменен, чтобы быть более согласованным с HEXw. формат. Когда HEXw. формат использует ширину 16 (соответствует 8 байтам данных), он генерирует шестнадцатеричное представление значения с плавающей запятой. BINARYW. формат, с тем чтобы ширина 57-64 создавала двоичное представление значения с плавающей запятой, так как ширина 57-64 соответствует 8 байтам данных.

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

BIN_64 = PUT (PUT (VALUE, S370FIB8.), $ BINARY64.);

S370FIB8. является format, который преобразует число их фиксированное целое двоичное представление, в формате IBM Mainframe. (Т. Е. Он записывает целое число в формате Big-Endian, что не то, что вы получили бы на машине Intel.)

+0

Я удалил бит в конце о том, почему значения являются «правильными», отчасти потому, что мой объяснение было недостаточно конкретным, а отчасти потому, что это действительно отдельный вопрос. Если вы хотите это знать (почему значение представления 'binary64', или' 001111111111000 ... ', верно для 1), задайте другой вопрос, и я поставлю там более подробный ответ. – Joe

+0

Кроме того, особенно если это повлияло на ваше программирование, рекомендуется добавить в TS билет с SAS об этом, поэтому они обновляют документацию. Документация SAS очень поражает и пропускает, и всегда полезно обновлять ее, когда вы видите что-то не хватает. – Joe

+0

Итак, возможно, как системное, так и * зависимое от версии поведение? Это скорее не подходит для SAS. Я согласен с тем, что некоторая лучшая документация, конечно, не повредит. – user667489