Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RPG Brain teaser

77 views
Skip to first unread message

Scott Ruthford

unread,
Dec 21, 2001, 12:03:04 PM12/21/01
to
I have an associate looking for a method to convert signed packed to
unsigned packed (preferably in RPG)

RPG does not support an unsigned packed data type, but a client asked
me if I could figure out a way to convert signed packed data to
unsigned packed. For example, packed numeric 12345:

convert signed packed (5,0) (3 bytes):
135
24F

to unsigned packed (3 bytes):
024
135

I have seen other postings going from unsigned to signed (no sweat)
but none going the other way.

Wyatt Taylor

unread,
Dec 21, 2001, 12:21:43 PM12/21/01
to
Simple.

Using your example, multiply the number by 10:

135
24F

becomes:

0240
135F

Move this field into character variable of the same length, then do a MOVEL
into a field that is one byte shorter.

That was fun.

"Scott Ruthford" <srut...@cardinalcorp.com> wrote in message
news:eb9978de.0112...@posting.google.com...

Thomas Hauber

unread,
Dec 21, 2001, 2:17:52 PM12/21/01
to
Why would you need to multiply by 10? If all you need is the number just move it into a character field straight off?

By the way this would be alot easier in RPG4.

Karl Hanson

unread,
Dec 21, 2001, 2:14:35 PM12/21/01
to

I believe the strict definition of "packed decimal" requires that the
rightmost nibble contain the sign. In the example above, the number
appears to be shifted right one nibble, truncating off the sign
nibble: 12345F -> 012345. This may be what you want, but I would
hesitate to use the result in any packed decimal arithmetic (RPG or
otherwise). Here are a couple references from Google search:

http://publibz.boulder.ibm.com:80/cgi-bin/bookmgr_OS390/BOOKS/DZ9AR005/8.1.2
http://www.cs.uno.edu/ClassPages/c2450/fall01/class_notes/10packed.PDF

If you want a valid packed decimal value that is always positive, you
could set the rightmost nibble to hex F (although A, C, and E are
described as valid alternatives on some systems).

--
Karl Hanson

Wyatt Taylor

unread,
Dec 21, 2001, 3:00:45 PM12/21/01
to
> Why would you need to multiply by 10? If all you need is the number just
move it into a character field straight off?

His number was packed decimal, which is stored differently than signed
numeric fields. In packed fields, each byte holds two digits. Each digit is
stored with four bits, 2 X 4 bits = 8 bits = one byte.

Multiply by 10 shifts all the digits one nibble, so that his number ends on
a byte boundary.

> By the way this would be alot easier in RPG4.

I can do it in three lines of code in any RPG flavor:

assume NUMBER is defined as P(3,0)

C NUMBER MULT 10 WORK# 4 0
C MOVE WORK# WORKA 4
C MOVELWORKA RESULT 3

Wyatt

"Thomas Hauber" <t...@hauber.com> wrote in message
news:fcf63574365a9045...@spamfreenews.com...

Wyatt Taylor

unread,
Dec 21, 2001, 3:39:35 PM12/21/01
to
I think his associate wants to use this data on some other platform. Lots of
languages and hardware support BCD (binary coded decimal), the iSeries has a
specific version which is called "packed". If I'm not mistaken, Java, C#,
and VB are some examples of languages that support BCD. Seems like I heard
even Intel hardware, Motorola and the PowerPC may have instructions for BCD
arithmetic.

BCD is used because binary numbers can't represent some decimal numbers
precisely: http://www2.hursley.ibm.com/decimal/decifaq.html

IIRC the AS/400 only likes packed data to have signs of 'F' or 'D', for +
and -, respectively. I can recall other IBM systems that will accept any
character other than 'F' as a negative number.

"Karl Hanson" <kcha...@us.ibm.com> wrote in message
news:3C238A1B...@us.ibm.com...

Barbara Morris

unread,
Dec 21, 2001, 6:20:34 PM12/21/01
to
Wyatt Taylor wrote:
> ...

> IIRC the AS/400 only likes packed data to have signs of 'F' or 'D', for +
> and -, respectively. I can recall other IBM systems that will accept any
> character other than 'F' as a negative number.
> ...

The AS/400 will accept any sign 'A' to 'F'. 'B' and 'D' are considered
negative. The AS/400 may differ from other systems in what it considers
the "preferred" sign, which is the sign that is generated when any
arithmetic is done on a packed or zoned value, and I think also on
assignment.

Dale A. Berta

unread,
Dec 22, 2001, 10:20:01 AM12/22/01
to
Your solution is great. Just one small improvement: instead of mucking about
with MOVEL, why not put the multiplication result and the character final
result into a DS, then you could read the 'unsigned packed' directly.

Or, if you needed to deal with variable lengths, you might be able to
softcode by multiplying into a larger packed field (say, 15P0) that's
overlayed in a DS with a char field, and then use %SST or SUBSTR on the char
field to get the final answer.

"Wyatt Taylor" <wwta...@swbell.net> wrote in message
news:HcKU7.1226$9o5.57...@newssvr11.news.prodigy.com...

Wyatt Taylor

unread,
Dec 22, 2001, 12:20:21 PM12/22/01
to
Thanks :-)

>why not put the multiplication result and the character final
> result into a DS, then you could read the 'unsigned packed' directly.

That would work. I love data structures, but if I'm writing something that's
a little tricky or clever, I prefer to do some of the string manipulation in
calc statements... just so that the next reader (or myself! six months
later) doesn't have to flip back to the DS statements and hold that mental
image in their mind. It's worth a few additional calc statements to be
clear... sometimes I think we sacrifice clarity for efficiency. Don't get me
wrong, 99.9% of the time I would use a DS, this is a case where I chose to
"show it in the code".

>then use %SST or SUBSTR on the char

I like that idea, it's more elegant than a MOVE and MOVEL.

I proposed this code because it is straightfoward.... and I don't see how it
could be done in less than 3 lines of code (including data structure or D
statement lines) and it works in any RPG dialect. And... I don't have to
look anywhere else in the program to understand how it works.


assume NUMBER is defined as P(3,0)

C* Convert iSeries packed number to packed decimal with no sign
C NUMBER MULT 10 WORK# 4 0 shift
packed digits one position left


C MOVE WORK# WORKA 4

move packed number to alpha field
C MOVELWORKA RESULT 3
trim off the sign and extra zero
C*

I keep talking in this thread about the number of lines of code, and that is
not my goal. My goal when I am programming is to make it as easy to
understand as possible.


"Dale A. Berta" <da...@fast.net> wrote in message
news:3c24a...@news7.fast.net...

Dave McKenzie

unread,
Dec 22, 2001, 1:24:31 PM12/22/01
to
...uhh...have you tried this code to see if it does what you expect?

--Dave

Wyatt Taylor wrote:

<snip>

> I proposed this code because it is straightfoward.... and I don't see how
> it could be done in less than 3 lines of code (including data structure or

> D statement lines) and it works in any RPG dialect...

Wyatt Taylor

unread,
Dec 22, 2001, 2:12:45 PM12/22/01
to
I have not tested it. It sounds like you think that you've discovered a flaw
in my logic.

Just to keep this thread interesting, I'd be willing to put a wager on it.


"Dave McKenzie" <dav...@zbiggroup.com> wrote in message
news:u29jvbj...@corp.supernews.com...

Dave McKenzie

unread,
Dec 22, 2001, 2:30:25 PM12/22/01
to
You're on. Loser has to post the following msg:

"OK, I admit it! I have been humbled by the world's most unsophisticated
language!"

--Dave

Wyatt Taylor

unread,
Dec 22, 2001, 2:40:52 PM12/22/01
to
Okay!! There is one condition I won't pay on, if you can't make it work and
others can.... of course.

Too bad it's not $$$$, I like to get paid for these teaching gigs.

I assume others in the NG will do this also and arbitrate the outcome.

I await the results... with great anticipation!!

Wyatt

"Dave McKenzie" <dav...@zbiggroup.com> wrote in message

news:u29nqv6...@corp.supernews.com...

Dave McKenzie

unread,
Dec 22, 2001, 3:10:13 PM12/22/01
to
Agreed.

--Dave

Obelix

unread,
Dec 22, 2001, 5:40:16 PM12/22/01
to
On Sat, 22 Dec 2001 17:20:21 GMT, "Wyatt Taylor" <wwta...@swbell.net>
wrote:

>just so that the next reader (or myself! six months


>later) doesn't have to flip back to the DS statements and hold that mental
>image in their mind.

That's what comments are for :-)))

Obelix

Njål Fisketjøn

unread,
Dec 23, 2001, 2:07:02 PM12/23/01
to
On Sat, 22 Dec 2001 19:40:52 GMT, "Wyatt Taylor" <wwta...@swbell.net> wrote:

>Okay!! There is one condition I won't pay on, if you can't make it work and
>others can.... of course.
>

> C* Convert iSeries packed number to packed decimal with no sign


> C NUMBER MULT 10 WORK# 4 0
> shift packed digits one position left
> C MOVE WORK# WORKA 4
> move packed number to alpha field
> C MOVELWORKA RESULT 3
> trim off the sign and extra zero

As soon as I saw Dave's post I had a thorough look at your code. I haven't tested it, but
moving a numeric variable to a character variable will not work (IMO)

NUMBER 123
WORK# 1230

hex:
020
13F

moved to character field will turn into

WORKA
FFFF
1230


Conclusion: you'll have to move (or multiply) to a DS subfield, and extract you RESULT
from the DS.


--
Njål Fisketjøn, FIGU DATA AS
n...@figu.no / http://www.figu.no

John Johnson

unread,
Dec 23, 2001, 7:14:45 PM12/23/01
to
I don't know if I understand this exactly right since I didn't get the first
post on my newsreader. But, the way I see it you want to convert a packed
three byte number with a sign to a packed four byte number with no sign. If
that is correct try this:

RPG/400:

THREE IFLT 0
Z-SUB THREE FOUR
ELSE
Z-ADD THREE FOUR
ENDIF

RPG IV:

If Three < 0
Eval Four = Three * -1
Else
Eval Four = Three
EndIf

Hope I got the question right and this helps. If not, as Emily Latella
(sp?) would say: "Never mind".

"Njål Fisketjøn" <n...@figu.no> wrote in message
news:b7ac2u8igi7tvfs66...@4ax.com...

Robert Dean

unread,
Dec 31, 2001, 10:10:15 AM12/31/01
to
Wyatt Taylor wrote:
[snip]

>
> IIRC the AS/400 only likes packed data to have signs of 'F' or 'D', for +
> and -, respectively. I can recall other IBM systems that will accept any
> character other than 'F' as a negative number.
[snip]

My only exposure to BCD other than AS/400, has been on an IBM mainframe
running MVS. It uses 'C' for positive, 'D' for negative, and treats
'F' as "unsigned."

SJ Lennon

unread,
Dec 31, 2001, 8:37:27 PM12/31/01
to
I'm fairly sure that IBM mainframes treat 'F' as positive. If you
packed a '1', which was X'F1' you got X'1F' which you could add or
subtract for other packed valued and it acted as would a positive
number.

I suppose it depends on what you mean by unsigned. Normally I would use
that for a binary field where the high order bit was not considered the
sign bit. In packed data we used "packed unsigned" to save disk space.
This trimmed of the last half byte.

Sam

"Robert Dean" <noe...@hatespam.spam> wrote in message
news:3C307FD7...@hatespam.spam...

Patrick Goupell

unread,
Jan 1, 2002, 12:23:11 PM1/1/02
to
IBM mainframe definitions were 'C' is positive, 'D' is negative. 'A',
'B' and 'F' are treated as a 'C' and 'E' is treated as a 'D'.

I don't know why, it is just what I remember from the 'Principles of
Operation' manuals.

--
Patrick Goupell

http://www.tax-gate.com
http://www.nite.org

Ugo Gagliardelli

unread,
Jan 2, 2002, 4:59:41 AM1/2/02
to

Patrick Goupell wrote:
>
> IBM mainframe definitions were 'C' is positive, 'D' is negative. 'A',
> 'B' and 'F' are treated as a 'C' and 'E' is treated as a 'D'.
>
> I don't know why, it is just what I remember from the 'Principles of
> Operation' manuals.

What I remember is the CAFE rule where C,A,F,E are treated as positives,
negatives otherwise when greater than 9. I think that unsigned packed
are not supported.
For example a file defined as 6 packed fields of 1 digit, displayed with
runqry results:
1A 1B 1C 1D 1E 1F
1 1- 1 1- 1 1

dsppfm +F10+F11 will show
*...+.

111111
ABCDEF

--
Dr.Ugo Gagliardelli,Modena,Italy-Certified uindoscrasher-AlcoolInside
Spaccamaroni andate a cagare/Spammers not welcome
Spamers iros a la mierda/Spamers allez vous faire foutre
Spammers loop schijten/Spammers macht Euch vom Acker

Wyatt Taylor

unread,
Jan 2, 2002, 9:41:48 AM1/2/02
to
Has anyone tried this yet?


Patrick Goupell

unread,
Jan 2, 2002, 11:10:04 AM1/2/02
to
Hey, you could be right on that (it has been soo long).

--

Njål Fisketjøn

unread,
Jan 2, 2002, 3:12:26 PM1/2/02
to
On Wed, 02 Jan 2002 14:41:48 GMT, "Wyatt Taylor" <wwta...@swbell.net> wrote:

>Has anyone tried this yet?
>

I WAS WRONG (or was I?):

>C NUMBER MULT 10 WORK# 4 0

>C MOVE WORK# WORKA 4

>C MOVELWORKA RESULT 3

If I change your sample code to define RESULT as a packed numeric (as the text implies)
RESULT is x'123F' after these 3 statements, and not the Zoned equivalent of 123 as I
thought. With your definition of RESULT as 3 alpha, my result would have been correct.

When I read your posting now, I think you meant RESULT to be 3,0 packed.

Wyatt Taylor

unread,
Jan 2, 2002, 3:16:00 PM1/2/02
to
No - make it a 3 alpha....


Wyatt Taylor

unread,
Jan 2, 2002, 3:20:21 PM1/2/02
to
> define RESULT as a packed numeric (as the text implies)

I think I clearly showed it as an alpha field. Try it with Result defined as
a 3 A field.


Njål Fisketjøn

unread,
Jan 2, 2002, 4:52:31 PM1/2/02
to

I did that too; RESULT is then x'F1F2F3'

Dave Caldwell

unread,
Jan 3, 2002, 4:36:23 PM1/3/02
to
When a packed decimal field is moved into a character field, the Zone
portion placed back (an "unpacking"
if you will) into the character field.

Given the following;

NUMBER is a packed field holding five decimal places (three bytes) with a
value of x'12345F'

The value in RESULT would be x'F3F4F5' or 345 character.

What you need is to do is perform binary operation. If you think about what
you are doing,
you are stripping the right most characters digit portion of the byte, then
"replacing it with
value of the Zone portion of the same byte, then move the Digit portion of
the second
rightmost byte into the Zone portion of the first byte, etc etc, until you
reach the leftmost
significant digit and then padding to the left with zeros.

Pictures are better than words
Value of the Field NUMBER, (A three byte field)

Byte 1 2 3

Zone 1 3 5
Digit 2 4 F

Byte 3 is the rightmost byte. You are "sliding zones into digits and digits
into zones.

Desired result would be
Byte 1 2 3

Zone 0 2 4
Digit 1 3 5

The only way I know (key phrase) how to do this is with Binary Arithmetic.
THIS IS NOT A TRIVIAL TASK.
What you need to do is determine what bits are on and off in each byte of
the packed field. (one byte at a time would
be the easiest way.) Then "slide" the values down by turning bits on or
off. I suggest you set off all bits off then only
turn on those which need to be on.

Hopefully, this is enough to get you started. I've got a headache just
describing this process. If you would like some
suggestions on exactly how this can be accomplished, you can e-mail me
directly at dave.c...@3x.com

Good Luck.
the values into there desired


"Njål Fisketjøn" <n...@figu.no> wrote in message

news:r4q63ugufudscmrae...@4ax.com...

Dave Caldwell

unread,
Jan 3, 2002, 5:06:46 PM1/3/02
to
I just looked in the ILE RPG for AS/400 Reference manual. It looks like
what you want may be done by
moving a packed field into an unsigned integer field. Too simple. Before I
would try my previously
recommended approach, I'd try that.


"Njål Fisketjøn" <n...@figu.no> wrote in message

news:q3073u8ng71qv9ngd...@4ax.com...

Barbara Morris

unread,
Jan 4, 2002, 12:55:47 PM1/4/02
to
Dave, as long as the original packed value is less than 30 digits,
there's an easy way to do this.

Define a character field with a packed overlay 1 digit longer than the
current value.
Assign 10 times the packed value to the packed overlay. Substring the
character field, leaving off the last byte.

packed value = x'12345F'
packed overlay = x'0123450F'
substring = x'012345'

0 new messages