Problem using z32. formatting

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 5
Accepted Solution

Problem using z32. formatting

Hello,

I need to make some binary numbers 32 digits long in order to split them up into 4 groups of 8. To do this I need to add 0s to the front, ie to the left. I've googled how SAS does this and come across what I've included in my example below. It seems for the longer original values SAS changes the number it is supposed to be adding 0s to.

Can anybody explain what is happening and possibly how to get round this?

Thanks

data urgh;

binaryval = 1000000;

put @1 binaryval z32.;

run;

output: 00000000000000000000000001000000

data urgh2;

binaryval = 10000001011011110100010110010000;

put @1 binaryval z32.;

run;

output: 10000001011011109659461967413248


Accepted Solutions
Solution
‎11-30-2012 07:30 AM
Frequent Contributor
Posts: 106

Re: Problem using z32. formatting

Maybe this helps you dealing with these numbers

data _null_ ;

  length bin_val $32. ;

  bin_val = '101' ;

  a = input(bin_val,binary32.) ;

  b1 = band(a,0ff000000x) / 256**3 ;

  b2 = band(a,000ff0000x) / 256**2 ;

  b3 = band(a,00000ff00x) / 256**1 ;

  b4 = band(a,0000000ffx) / 256**0 ;

  put a= a=hex8. a=binary32.

  / (b1-b4) (=z3. )

  / (b1-b4) (=hex2. )

  / (b1-b4) (=binary8.)

  / 50*'-' ;

  bin_val = '10000001011011110100010110010000' ;

  a = input(bin_val,binary32.) ;

  b1 = band(a,0ff000000x) / 256**3 ;

  b2 = band(a,000ff0000x) / 256**2 ;

  b3 = band(a,00000ff00x) / 256**1 ;

  b4 = band(a,0000000ffx) / 256**0 ;

  put a= a=hex8. a=binary32.

  / (b1-b4) (=z3. )

  / (b1-b4) (=hex2. )

  / (b1-b4) (=binary8.)

  / 50*'-' ;

  stop ;

run ;

Variables B1 through B4 should correspond to the 8 bit grouped values you mentioned.

View solution in original post


All Replies
Solution
‎11-30-2012 07:30 AM
Frequent Contributor
Posts: 106

Re: Problem using z32. formatting

Maybe this helps you dealing with these numbers

data _null_ ;

  length bin_val $32. ;

  bin_val = '101' ;

  a = input(bin_val,binary32.) ;

  b1 = band(a,0ff000000x) / 256**3 ;

  b2 = band(a,000ff0000x) / 256**2 ;

  b3 = band(a,00000ff00x) / 256**1 ;

  b4 = band(a,0000000ffx) / 256**0 ;

  put a= a=hex8. a=binary32.

  / (b1-b4) (=z3. )

  / (b1-b4) (=hex2. )

  / (b1-b4) (=binary8.)

  / 50*'-' ;

  bin_val = '10000001011011110100010110010000' ;

  a = input(bin_val,binary32.) ;

  b1 = band(a,0ff000000x) / 256**3 ;

  b2 = band(a,000ff0000x) / 256**2 ;

  b3 = band(a,00000ff00x) / 256**1 ;

  b4 = band(a,0000000ffx) / 256**0 ;

  put a= a=hex8. a=binary32.

  / (b1-b4) (=z3. )

  / (b1-b4) (=hex2. )

  / (b1-b4) (=binary8.)

  / 50*'-' ;

  stop ;

run ;

Variables B1 through B4 should correspond to the 8 bit grouped values you mentioned.

Occasional Contributor
Posts: 5

Re: Problem using z32. formatting

Posted in reply to Robert_Bardos

Thank you very much for this. There is another step that I am unable to do which is basically some binary subtraction within SAS.

I need to do these equations using the b1, b2, b3 and b4 obtained but in binary form. eg. 1010 - 1101 = 0111

c1 = b1 - b2 ;

c2 = c1 - b3 ;

c3 = c2 - b4 ;

Is this possible within SAS?

Frequent Contributor
Posts: 106

Re: Problem using z32. formatting

data _null_ ;

    a = input('1010',binary4.) ;

    b = input('1101',binary4.) ;

    c = bnot(band(a,b)) ;

    put (a--c) (=binary4.) ;

    stop ;

run ;

Occasional Contributor
Posts: 5

Re: Problem using z32. formatting

Posted in reply to Robert_Bardos

Your replies have been very helpful so far.

So far I have several pieces of code which require the user to input some numbers at various points. I'm looking to make the process more automated if possible, maybe just entering one number at the start.

The user is required to enter "value" and "i" (which will allows be the case) and the first bit converts the value to binary and outputs it. The second part requires the user to input the binary value "bin_val". This is then converting to 32 bit and broken up into the four 8 bits. The third part requires the user to enter these four 8 bits and comes out with a cell in a table.

Is it possible to combine these parts to require the user to have to do less inputting? I've tried myself but can't get the code right.

data urgh;

value= 84738654654645654;

i = 5;

put i; call symput('i',compress(i));

key= mod(value,4294967296);

put @1 key binary32.;

run;

data _null_ ;

  length bin_val $32. ;

  bin_val = '10000001011011110100010110010000' ;

  a = input(bin_val,binary32.) ;

  b1 = band(a,0ff000000x) / 256**3 ;

  b2 = band(a,000ff0000x) / 256**2 ;

  b3 = band(a,00000ff00x) / 256**1 ;

  b4 = band(a,0000000ffx) / 256**0 ;

  put a= a=hex8. a=binary32.

  / (b1-b4) (=z3. )

  / (b1-b4) (=hex2. )

  / (b1-b4) (=binary8.)

  / 50*'-' ;

    stop ;

run ;

data _null_ ;

    a = input('00110110',binary8.) ;

    b = input('11011111',binary8.) ;

    c = input('01011001',binary8.) ;

    d = input('10111110',binary8.) ;

    e = bxor(a,b) ;

    f = bxor(e,c) ;

    g = bxor(f,d) ;

    put (a--g) (=binary8.) ;

    h = g+1;

    put h; call symput('h',compress(h));

    if &i<21 then j = 5;

    else j = 21 + mod(i,10)-1; 

    put j; call symput('j',compress(j));

    stop ;

run ;

data work.blah;

set work.table (keep=VAR&j);

if _n_=&h;

run;

Frequent Contributor
Posts: 106

Re: Problem using z32. formatting

I guess I'm not following (and I hope this is not part of some hacking attempt). Could you perhaps rephrase your intent?

Somewhat like:

  • I have an initial numeric value X
  • X shall be transformed to ?1
  • ?1 shall further be transformed to ?2
  • etc
  • the result shall be used to <please explain>

Anybody who is following the original poster's intent better than I is invited to jump in!

Regards

Robert

Occasional Contributor
Posts: 5

Re: Problem using z32. formatting

Posted in reply to Robert_Bardos

This is for disclosure control in order to slightly alter a value using the table that is referred to.

I have the two initial values, "value" and "i", which are manually input.

The "value" is converted to binary.

The user then manually inputs this binary value as "bin_val".

"bin_val" is then converted to 32 bit and then split into four 8 bits.

The user then has to manually input these four 8 bits.

These four 8 bits are then used to calculate "h".

Using "h" and "i" a cell is found in a table.

The value of this cell is a number which will then be added to "i" (although this isn't in the code yet), which will be the result.

I am wondering if it is possible to use macros or some other method so that the user is only required to manually input "value" and "i" and the result is the value looked up in the table?

Frequent Contributor
Posts: 106

Re: Problem using z32. formatting

O.k., thanks for clarifying. Should easily be doable by substituting 'user' by some transport medium between data steps or maybe even better: within a single data step.

Such transport media may be

  • macro variables
  • SAS variables (if within the same datastep)
  • SAS data sets and their respective variables
  • external (temporary) files
  • maybe others that escape me right now

So your code might look somewhat like:

%let initial_value1 =  <value_to_be_entered_by_user> ;

%let initial_value2 =  <value_to_be_entered_by_user> ;

data _null_ ;

       bin32_value = put(&initial_value1,binary32.) ;

       * <some code to generate the four 8bit string values> ;

       bin8_1 = band(&initial_value1,0ff000000x) / 256**3; /* numeric form */

       bin8_2 = band(&initial_value1,000ff0000x) / 256**2;

       bin8_3 = band(&initial_value1,00000ff00x) / 256**1;

       bin8_4 = band(&initial_value1,0000000ffx) / 256**0;

       put8_1 = put(bin8_1,binary8.) ;

       *.... ;

       put8_4 = put(bin8_4,binary8.) ;  /* string form */

       * <some code to calculate "h"> ;

       h =  <some operations involving bin8_1 through bin8_4 or put8_1 through put8_4> ;

       call symput('calculated_h',h) ;

run ;

proc sql ;

     select sum(cell_number, &inital_value2) into :result_value

       from table

     where cell_var1 eq &calculated_h and cell_var2 eq &initial_value2 ;

quit :

%put result_value is &result_value ;

All this entirely untested (especially the SQL part). Hope it gives you some ideas.

Super User
Super User
Posts: 7,050

Re: Problem using z32. formatting

Use the BINARY format instead of the Z format to display (or convert) a number to binary digits.

To split into pieces you can either subset the string of ones and zeros produced by the binary format or use modular arithmetic functions on the original number.

data _null_;

put '*** Mathematical ***' ;

  b1=5 ;

  b2=3 ;

  b3=125 ;

  b4=129 ;

  put '4 Numbers ' @20 (b1 - b4 ) (binary8. ) ;

  x = b1*256**3 + b2*256**2 + b3*256 + b4 ;

  put '1 Number  ' @20 x binary32. ;

  nb1 = int(x / 256**3);

  nb2 = mod(int( x / 256**2 ), 256 );

  nb3 = mod(int( x / 256 ), 256 );

  nb4 = mod(x,256);

  put 'New numbers ' @20 (nb1 - nb4 ) (binary8. ) ;

put '*** String ***' ;

  xc = put(x,binary32.);

  put '1 String ' @20 xc ;

  c1=substr(xc,1,8);

  c2=substr(xc,9,8);

  c3=substr(xc,17,8);

  c4=substr(xc,25,8);

  put '4 Strings ' @20 (c1 - c4 ) ($8.) ;

run;

*** Mathematical ***

4 Numbers          00000101000000110111110110000001

1 Number           00000101000000110111110110000001

New numbers        00000101000000110111110110000001

*** String ***

1 String           00000101000000110111110110000001

4 Strings          00000101000000110111110110000001

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 8 replies
  • 415 views
  • 3 likes
  • 3 in conversation