Inverse ascii with numreic

Hi,

I do this:


#a (a10)
#b (a10)
move left #a (pm=i) to #b

which inverse my string, but I need more:
I need that if there is a numeric value in a row (more than 1 digit),
not to inverse the numeric.
ex:

#a := 'abc123defg'
#b := 'gfed123cba'

another question:
How to convert binary and hex to decimal and vice versa?

Thanks

Hezi,

I don’t think we have enough information here. Will the numbers always be in the center of the string or can they be scattered? Will there be any spaces in the string to deal with?

I suspect you are going to have to do a byte by byte logic to get this done.

How would you want the following to come out?
“a1b2c3d4”
“1234abcd”
“a1b2cdef”
“ab cd ef”

Hi,

well I mean this:
1.

move #a (pm=i) to #b

to inverse the string
2. Inverse any number in a string that is 2 digit in a row or more

ex: ‘abc12de123f1’ --> ‘abc21de321f1’

Hezi

This is very similar to an old question/thread from a couple of years ago.

I posted what turned out to be the fastest solution, which resulted from using SEPARATE with the digits 0 through 9 as delimiters.

Depending on your answers to Jerome’s posting, the following code may suggest an appropriate solution:

DEFINE DATA LOCAL
1 #IN (A20) INIT <‘QWERT12ASDFG’>
1 #OUT (A20)
1 #TEMP (A/1:10) DYNAMIC
1 #NUM (I2)
END-DEFINE
*
INCLUDE AATITLER
*
SEPARATE #IN INTO #TEMP (*) WITH
RETAINED DELIMITERS ‘0123456789’
GIVING NUMBER #NUM
*
PRINT #TEMP (1) / #TEMP (2) / #TEMP (3) / #TEMP (4) /
#TEMP (5) / #TEMP (6)
*
WRITE LENGTH (#TEMP ()) / #NUM
END

PAGE #   1                    DATE:    09-08-20
PROGRAM: REVERS01             LIBRARY: INSIDE

QWERT
1

2
ASDFG

      5           1           0           1           5           0
      0           0           0           0
 5

If #NUM is a 1, there are no digits in the string.
If #NUM is a 3, there is a single digit in the string (no reversal required)
If #NUM is a 5, there is either a 2 digit string (there will be a sequence 101 in the lengths of #TEMPs, or two one digit strings (no reversal required)).

You can play with this depending on exactly what you require.

steve

Here is a link to the old thread:

http://tech.forums.softwareag.com/viewtopic.php?t=7641&start=0&postdays=0&postorder=asc&highlight=&sid=e358fa62c5d2b4fb692392c52ac09376

It was from June 2007.

steve

Just noticed the other part of your post:

"How to convert binary and hex to decimal and vice versa? "

For Binary Variables with length less than 5, this is trivial, since Natural basically treats B1…B4 as numeric.

DEFINE DATA LOCAL
1 #B (B4) INIT <987654321>
1 #N (N12)
END-DEFINE
*
INCLUDE AASETCR
INCLUDE AATITLER
*
COMPUTE #N = #B
WRITE 5T ‘=’ #N 10X ‘=’ #B
END

PAGE #   1                    DATE:    09-08-22
PROGRAM: BIN01                LIBRARY: INSIDE

#N:     987654321          #B: 3ADE68B1

Note that if #B was B5, the program would not compile.

The converse is just as simple:

DEFINE DATA LOCAL
1 #B (B4)
1 #N (N12) INIT <987654321>
END-DEFINE
*
INCLUDE AASETCR
INCLUDE AATITLER
*
COMPUTE #B = #N
WRITE 5T ‘=’ #B
END
PAGE # 1 DATE: 09-08-22
PROGRAM: BIN02 LIBRARY: INSIDE

#B: 3ADE68B1

Note that #B in BIN02 is the same as in BIN01.

steve

define data local
01 #a (A) dynamic init <'1234abc5678hijklm5678'>
01 #b (A) dynamic
01 #i1 (I4)
01 #numeric (A) dynamic
01 #from   (I4)
01 #length (I4)
end-define
move #a (pm=i) to #b
for #i1 := 1 to *LENGTH(#b) 
  if substr(#b,#i1,1) = MASK(N)
    if #from = 0
      #from := #i1
    end-if
    add 1 to #length
  else
    perform move-substr
    reset #from #length
  end-if
end-for
perform move-substr
display #a (AL=50)
display #b (AL=50)
*
define subroutine move-substr
  if #from > 0 and #length > 1
    move substr(#b,#from,#length) (PM=I) to substr(#b,#from,#length)
  end-if
end-subroutine
*
end

… maybe you have to search for decimal separators and date values as well.

Hopefully, this does not “double post”; but the first post did not seem to work:

Here is an alternate program:

DEFINE DATA LOCAL
1 #IN (A30) INIT <‘1234abc5678hijklm5678’>
1 #OUT (A30)
1 #TEMP (A/1:30) DYNAMIC
1 #NUM (I2)
1 #LOOP (I2)
1 #TIMER (I2)
1 #ONE (A1)
END-DEFINE
*
SEPARATE #IN INTO #TEMP () WITH
RETAINED DELIMITERS ‘0123456789’
GIVING NUMBER #NUM
*
FOR #LOOP = 1 TO #NUM
MOVE #TEMP (#LOOP) TO #ONE
IF #ONE NE ’ ’ AND #ONE NE MASK (N)
MOVE #TEMP (#LOOP) (PM=I) TO #TEMP (#LOOP)
END-IF
END-FOR
*
COMPRESS #TEMP (
) INTO #OUT LEAVING NO SPACE
WRITE #IN / #OUT
END

Page 1 09-08-24 07:41:45

1234abc5678hijklm5678
1234cba5678mlkjih5678

On my PC the code above and Matthias’s code have about the same CPU time.

Would appreciate confirmation that the two programs are indeed what is required, then will do elapsed timings and also mainframe timings; then look to improve them.

steve

Hi,

Thanks a lot.

Hi Hezi;

Just a performance report for the two programs.

On my PC, using the data string Matthias first used, the CPU time favored Matthias’s code by 53-55.

However, using a string of init <‘abcdabc56hijklmghijqwertasdfg’>, the numbers change dramatically; 64-26 in favor of my code.

Basically, Matthias’s code is more “consistent”, CPU time is mainly a function of the length of the string. My code is sensitive to the number of digits more than the length of the string.

So, you might want to consider what the expected data looks like when deciding which code excerpt to use.

steve