TOPIC: HEXADECIMAL
Something to watch with the SYSODSESCAPECHAR automatic SAS macro variable
10th October 2021Recently, a client of mine updated one of their systems from SAS 9.4 M5 to SAS 9.4 M7. Despite performing due diligence regarding changes between the maintenance release, a change in behaviour of the SYSODSESCAPECHAR
automatic macro variable surprised them. The macro variable captures the assignment of the ODS escape character used to prefix RTF codes for page numbering and other things. That setting is made using an ODS ESCAPECHAR
statement like the following:
ods escapechar="~";
In the M5 release, the tilde character in this example was output by the automatic macro variable, but that changed in the M7 release to 7E, the hexadecimal code for the same and this tripped up one of their validated macro programs used in output production. The adopted solution was to use the escape sequence (*ESC*) that gave the same outcome that was there before the change. That was less verbose than alternative code changing the hexadecimal code into the expected ASCII character that follows.
data _null_;
call symput("new",byte(input("&sysodsescapechar.",hex.)));
run;
The above supplies a hexadecimal code to the BYTE function for correct rendering, with the SYMPUT
routine assigning the resulting value to a macro variable named new. Just using the escape sequence is far more succinct, though there is now an added validation need once user pilot testing has completed. In my line of business, the updating of code is the quickest part of many such changes; documentation and testing always take longer.
Octals in UNIX shell scripting
9th February 2007I have just discovered that if you have a number with a leading zero, such as 08
, it is assumed to be an octal number, that is, one of base 8. The upshot of this is that you get errors when you have numbers like 08
and 09
in your arithmetical expressions; they are illegal in octal: 08
should be 10
and 09
should be 11
. Of course, as luck would have it, you get exactly these expressions when date/time processing. Luckily, you can force things to be base 10 by having something like 10#08
or, when extracting the minute from a date-time value, 10#$(date +%M)
. Strange as it might appear, this behaviour is all by design. It is dictated in the POSIX standard that governs UNIX. That said, I'd rather it if 08 was interpreted as an 8 and 09 as a 9 rather than triggering the errors that we see, but that could have been seen as muddying the simplicity of the standard.