Calcite | Level 5

## how to find the difference between two hex data

Hi,

I have two hex data.

start                              end                             hex diff   decimal diff

00000485576688D7    000004855767176D   8E96       36502

how can I use informat to input the data then calculate the difference then print these values with format hex output as above?

Thanks David

1 ACCEPTED SOLUTION

Accepted Solutions

## Re: how to find the difference between two hex data

Hi @yuwda01,

For those later readers who need to compute the exact difference D=X−Y between two non-negative hexadecimal integers X and Y of up to 26 hex digits each, here's an approach splitting the long numbers into two of length <=13 (which enables storage in a numeric variable). The result is given as a right-justified 27-character string in hexadecimal format (26 digits, padded with zeros) with a minus sign for negative numbers and a leading blank for non-negative numbers.

``````/* Create test data for demonstration */

data have;
length x y \$26;
input x char26. +1 y char26.;
cards;
000004855767176D           00000485576688D7
004855767176D        485576688D7
FEDCBA9876543210ABCDEF6789 1234567890ABCDEF0987654321
1234567890ABCDEF0987654321 FEDCBA9876543210ABCDEF6789
F                              5
1                          c
a20529f5cca196DA           a20529f5cca196d8
0                          a20529f5cca196d8
a20529f5cca196d8           a20529f5cca196d8
;

/* Compute the differences D=X-Y */

data want(drop=m0 m1 n0 n1 lx ly);
set have;
length d \$27;
lx=length(left(x));
ly=length(left(y));
m0=input(substr(right(x),max(1,length(right(x))-12)), hex13.); /* last (up to) 13 hex digits */
n0=input(substr(right(y),max(1,length(right(y))-12)), hex13.);
if lx>13 then m1=input(substr(left(x),1,lx-13), hex13.);  /* remaining (up to 13) hex digits */
else m1=0;
if ly>13 then n1=input(substr(left(y),1,ly-13), hex13.);
else n1=0;
if m1>n1 | m1=n1 & m0>=n0 /* i.e. "if x>=y" */
then d=' '||put(m1-n1-(m0<n0), hex13.)||put(16**13*(m0<n0)-n0+m0, hex13.);
else d='-'||put(n1-m1-(n0<m0), hex13.)||put(16**13*(n0<m0)-m0+n0, hex13.);
run;``````

The examples show that alignment, leading zeros or capitalization don't affect the result.

13 REPLIES 13
Tourmaline | Level 20

## Re: how to find the difference between two hex data

From the documentation:

When you specify a [width]] value of 1 through 15, the input hexadecimal value represents an integer binary number. When you specify 16 for the [width] value, the input hexadecimal value represents a floating-point value.

``````data HAVE;
START= '00000485576688D7';
END  = '000004855767176D';
S16  = input(END  ,hex16.);
E16  = input(START,hex16.);
S14  = input(substr(END  ,3),hex14.);
E14  = input(substr(START,3),hex14.);
DIFF = E14-S14;
run;``````

START END S16 E16 S14 E14 DIFF
00000485576688D7 000004855767176D 0.024E-309 0.024E-309 4970743535469 4970743498967 -36502

[Edit:  To print the value in hex format, use the hex format 🙂  ]

Tourmaline | Level 20

## Re: how to find the difference between two hex data

If you do have numbers with 16 hexadecimal digits (which exceeds the precision offered by SAS integer values) you can read them like this to get an approximate decimal value:

``````data WANT;
HEX    = '11111485576688D7';
DEC15  = input(substr(HEX,2),hex15.);
DEC1   = input(HEX  ,hex1.);
NUMBER = DEC1*16**15 + DEC15;
run;``````

NUMBER=1.2297867E18

Opal | Level 21

## Re: how to find the difference between two hex data

Because you only need a numerical data type intermediary without the need to store it in a SAS table: Could using Proc DS2 with a BIGINT eventually allow to deal with more than 16 digits with full precision?

Tourmaline | Level 20

## Re: how to find the difference between two hex data

To go back to the original question, and assuming the first hex digit can be discounted, this works:

``````data HAVE;
START= '00000485576688D7';
END  = '000004855767176D';
S15  = input(substr(START,2),hex15.);
E15  = input(substr(END  ,2),hex15.);
DIFF = E15-S15;
putlog DIFF= 6. DIFF= hex.;
run;``````

DIFF=36502 DIFF=00008E96

PROC Star

## Re: how to find the difference between two hex data

You can test what answers you are getting against the logic below, but I would think that 14 hex digits is too many for SAS to accurately store.  Notice however, that you don't need to use them all:

00000485576688D7    000004855767176D

These strings are the same for the first 11 characters.  You only need to compute:

diff = input( substr(end, 12), hex5.) - input(substr(start, 12), hex5.) ;

Calcite | Level 5

## Re: how to find the difference between two hex data

here is my code.

data log;
infile 'ZKQMMM9.REPORT(QT9ALOG1)';
input @1 start ymddttm19.
@24 end  ymddttm19.
@46 startrba  hex16.
@65 endrba    hex16.
;
run;
data log1; set log;
time_diff = end-start;
rba_diff = endrba -startrba;
run;
PROC PRINT DATA=log1 SPLIT="*";
var start end time_diff
startrba endrba rba_diff
;
format start end E8601DT19.0
format time_diff time8.0
startrba endrba hex16. rba_diff hex.
;
RUN;

and here is my output

time_
Obs    start                  end                        diff            startrba              endrba    rba_diff

1    2019-04-17T04:18:22    2019-04-17T06:36:57     2:18:35    00000485576688D7    000004855767176D    00000000
2    2019-04-17T02:50:20    2019-04-17T04:18:22     1:28:02    0000048552DD6F2E    0000048552DDFF70    00000000
3    2019-04-17T02:39:09    2019-04-17T02:50:20     0:11:11    00000485514BCEF7    00000485514C7A09    00000000
4    2019-04-17T01:24:04    2019-04-17T02:39:09     1:15:05    000004854E328DED    000004854E3328DB    00000000
5    2019-04-17T01:19:17    2019-04-17T01:24:04     0:04:47    000004854A13562D    000004854A13FB15    00000000

I have two issues I would like to resolve.

1) rba_diff is not shown.

2) instead display time with 2019-04-17T04:18:22    I would like to display without T between date and time.  2019-04-17 04:18:22

Thanks David

PROC Star

## Re: how to find the difference between two hex data

For the first question, note that RBA_DIFF is being displayed.  It is 0 all the time, because SAS isn't able to store the values for STARTRBA and ENDRBA with sufficient precision to tell the difference.  I suggest you apply my earlier suggestion and don't try to store the entire value.  For example:

``````data log;
infile 'ZKQMMM9.REPORT(QT9ALOG1)';
input @1 start ymddttm19.
@24 end  ymddttm19.
@46 startrba  \$16.
@65 endrba    \$16.
;
rba_diff = input( substr(endrba, 11), hex6.)
- input( substr(startrba, 11), hex6.) ;
run;                  ``````

For the datetime variables, SAS supplies many datetime formats.  You chose E8601DT19.0  but you don't have to use that one.  Here are some other choices:

http://support.sas.com/documentation/cdl/en/leforinforref/63324/HTML/default/viewer.htm#n0av4h8lmnkt...

These days, there are even ways to create your own datetime format using PROC FORMAT.

Calcite | Level 5

## Re: how to find the difference between two hex data

thank you for the information.  You have answered all my questions.

## Re: how to find the difference between two hex data

Hi @yuwda01,

For those later readers who need to compute the exact difference D=X−Y between two non-negative hexadecimal integers X and Y of up to 26 hex digits each, here's an approach splitting the long numbers into two of length <=13 (which enables storage in a numeric variable). The result is given as a right-justified 27-character string in hexadecimal format (26 digits, padded with zeros) with a minus sign for negative numbers and a leading blank for non-negative numbers.

``````/* Create test data for demonstration */

data have;
length x y \$26;
input x char26. +1 y char26.;
cards;
000004855767176D           00000485576688D7
004855767176D        485576688D7
FEDCBA9876543210ABCDEF6789 1234567890ABCDEF0987654321
1234567890ABCDEF0987654321 FEDCBA9876543210ABCDEF6789
F                              5
1                          c
a20529f5cca196DA           a20529f5cca196d8
0                          a20529f5cca196d8
a20529f5cca196d8           a20529f5cca196d8
;

/* Compute the differences D=X-Y */

data want(drop=m0 m1 n0 n1 lx ly);
set have;
length d \$27;
lx=length(left(x));
ly=length(left(y));
m0=input(substr(right(x),max(1,length(right(x))-12)), hex13.); /* last (up to) 13 hex digits */
n0=input(substr(right(y),max(1,length(right(y))-12)), hex13.);
if lx>13 then m1=input(substr(left(x),1,lx-13), hex13.);  /* remaining (up to 13) hex digits */
else m1=0;
if ly>13 then n1=input(substr(left(y),1,ly-13), hex13.);
else n1=0;
if m1>n1 | m1=n1 & m0>=n0 /* i.e. "if x>=y" */
then d=' '||put(m1-n1-(m0<n0), hex13.)||put(16**13*(m0<n0)-n0+m0, hex13.);
else d='-'||put(n1-m1-(n0<m0), hex13.)||put(16**13*(n0<m0)-m0+n0, hex13.);
run;``````

The examples show that alignment, leading zeros or capitalization don't affect the result.

Calcite | Level 5

## Re: how to find the difference between two hex data

Hi,

how can I mark the most helpful answer as the accepted solution?

Thanks David

## Re: how to find the difference between two hex data

@yuwda01 wrote:

how can I mark the most helpful answer as the accepted solution?

1. Click on the blue gear icon (shown below) of the currently accepted solution to open the "option menu."
2. Select "Not the Solution" from that menu.
3. Click the "Accept as Solution" button of the real solution (or select "Accept as Solution" from the option menu of that post).
Tourmaline | Level 20