turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- SAS Procedures
- /
- How to add two long digital text strings

Topic Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-11-2015 09:04 AM

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?

Accepted Solutions

Solution

03-11-2015
06:01 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Yoram101

03-11-2015 06:01 PM

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;

All Replies

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Yoram101

03-11-2015 09:52 AM

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.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Yoram101

03-11-2015 10:01 AM

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!

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-11-2015 10:26 AM

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.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-11-2015 10:32 AM

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.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Yoram101

03-11-2015 10:41 AM

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".

---------------------------------------------------------------------------------------------

Maxims of Maximally Efficient SAS Programmers

How to convert datasets to data steps

How to post code

Maxims of Maximally Efficient SAS Programmers

How to convert datasets to data steps

How to post code

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Yoram101

03-11-2015 11:12 AM

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

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Ksharp

03-11-2015 12:04 PM

Keshan, that is a neat code. Thanks.

Solution

03-11-2015
06:01 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Yoram101

03-11-2015 06:01 PM

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;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to billfish

03-11-2015 07:08 PM

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.