BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Yoram101
Calcite | Level 5

Simplified Example:

txt1= '000350000400321000350000400321000350000400321'

txt2= '000060000200032000060000200032000060000200032'

sum='000410000600353000410000600353000410000600353' -->Wish to get.


The example txt strings are strings of individual counts, each occupying 5 digits.

I need to add each pair of counts in their position.

In my case, each string is 235 digits long. Informat is limited to 30 or 31 wide.

where sum=txt1+txt2.


Of course I can read each count, add them up and re-form the sum string but I wonder if there is another, simpler way such as: adding long text strings, converting to integers, Boolean, binary, hex?

1 ACCEPTED SOLUTION

Accepted Solutions
billfish
Quartz | Level 8

A little bit generalized solution, if one has more than 2 txt# variables and if cannot break all the txt# in regular substrings.

Of course one needs some leading zeros in the txt#'s to be summed.

/*************************/
/*** proposed solution ***/
/*************************/
data have(keep=txt:);
  array txt(3) $45;
  txt1= '000350000400321000350000400321000350000400321';
  txt2= '000060000200032000060000200032000060000200032';
  txt3= '';
  zLeftOver=0;
  do i = 1 to 45;
     k=zLeftOver;
     do j = 1 to (dim(txt)-1);
        k+input(substr(txt(j),45-i+1,1),1.);
     end;
     zLeftOver=int(k/10);
     txt3=cats(mod(k,10),txt3);
  end;
run;

View solution in original post

9 REPLIES 9
Astounding
PROC Star

There's no "pure" solution, since SAS has a limit of 15 to 16 significant digits for numerics.  You could try splitting the text into 24 parts, each 10 digits long.  SAS would be able to add those.  When reassembling the three totals, you would have to account for totals that require 11 digits instead of 10.  Your original thought of splitting into 5-digit parts would be just as good.

Good luck.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

As Astounding has said, it is not directly possible.  I remember seeing  a post from FriedEgg where he used proc groovy or something along those lines to utilise Java objects to process very large numbers.  I would question though why you want to do this.  What do those "numbers" actually mean, do you need them as one whole like that, can you not subdivision your data into groups to reduce the size of the number.  A number that size is rather rare outside astrological dimensions!

Yoram101
Calcite | Level 5

Each group of records has a header record and a trailer record with record counts by record type. There are at least 17 record type counts in the trailer. Each in an 8 digits field. I want to join 2 groups together and have their total count in a new trailer record.

This is not my data. I have no control of the data or its format.

Yoram101
Calcite | Level 5

However, if it is not possible then I'll have to resort to reading each count separately, add the proper ones, and proceed to reassemble the new trailer with these sums.

thanks for your help.

Kurt_Bremser
Super User

You are best off with doing this in a do loop that processes 5 digits per iteration. In the end, the code will basically document itself, making clear that each 5-digit block is a separate entity.

Any "clever" solution could hide that fact and make it harder to decipher what's going on.

In this regard, I think this a typical example for Ken Thompson's "If in doubt, use brute force".

Ksharp
Super User

I am afraid you have to split it into tokens and sum them and combine them after that.

data have;
txt1= '000350000400321000350000400321000350000400321';
txt2= '000060000200032000060000200032000060000200032';
length txt_sum $ 200;
do i=1 to length(txt1) by 5;
 sum=input(substr(txt1,i,5),best32.)+input(substr(txt2,i,5),best32.);
 txt_sum=cats(txt_sum,put(sum,z5.));
end;
drop sum i;
run;

XIa Keshan

Yoram101
Calcite | Level 5

Keshan, that is a neat code. Thanks.

billfish
Quartz | Level 8

A little bit generalized solution, if one has more than 2 txt# variables and if cannot break all the txt# in regular substrings.

Of course one needs some leading zeros in the txt#'s to be summed.

/*************************/
/*** proposed solution ***/
/*************************/
data have(keep=txt:);
  array txt(3) $45;
  txt1= '000350000400321000350000400321000350000400321';
  txt2= '000060000200032000060000200032000060000200032';
  txt3= '';
  zLeftOver=0;
  do i = 1 to 45;
     k=zLeftOver;
     do j = 1 to (dim(txt)-1);
        k+input(substr(txt(j),45-i+1,1),1.);
     end;
     zLeftOver=int(k/10);
     txt3=cats(mod(k,10),txt3);
  end;
run;

Yoram101
Calcite | Level 5

One gets comfortable programing in a certain way and not until proposing a challenge to our forum that he finds out the many clever ways to skin a cat. This approach comes closest  to performing a direct binary add on these text strings.

thanks billfish. Your way is not limited to two strings, does not depend on the text's length, nor on the logical field division within the string. Much appreciated. Thank you all.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1302 views
  • 3 likes
  • 6 in conversation