Return-Path: <root@fatcity.cts.com>
Received: from ensim.rackshack.net (root@localhost)
 by orafaq.net (8.11.6/8.11.6) with ESMTP id g9AKuGC21354
 for <oracle-l@orafaq.net>; Thu, 10 Oct 2002 15:56:16 -0500
X-ClientAddr: 209.68.248.164
Received: from newsfeed.cts.com (newsfeed.cts.com [209.68.248.164])
 by ensim.rackshack.net (8.11.6/8.11.6) with ESMTP id g9AKtQD21216
 for <oracle-l@orafaq.net>; Thu, 10 Oct 2002 15:55:33 -0500
Received: from fatcity.UUCP (uucp@localhost)
 by newsfeed.cts.com (8.9.3/8.9.3) with UUCP id LAA51839;
 Thu, 10 Oct 2002 11:30:18 -0700 (PDT)
Received: by fatcity.com (26-Feb-2001/v1.0g-b72/bab) via UUCP id 004E5F94; Thu, 10 Oct 2002 10:05:00 -0800
Message-ID: <F001.004E5F94.20021010100500@fatcity.com>
Date: Thu, 10 Oct 2002 10:05:00 -0800
To: Multiple recipients of list ORACLE-L <ORACLE-L@fatcity.com>
X-Comment: Oracle RDBMS Community Forum
X-Sender: "Tim Gorman" <Tim@SageLogix.com>
Sender: root@fatcity.com
Reply-To: ORACLE-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
From: "Tim Gorman" <Tim@SageLogix.com>
Subject: Re: Packed decimal
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0g, build 72; ListGuru (c) 1996-2001 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: multipart/alternative;	boundary="----=_NextPart_000_034B_01C2704C.8B7B6360"
------=_NextPart_000_034B_01C2704C.8B7B6360
Content-Type: text/plain;
 charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

SQL*Loader understands how to translate PACKED and ZONED DECIMAL format; =
 pretty sure that PRO*Cobol does as well, though I don't do Cobol...

If you're interested in conversion routines, I've a "C" function named =
"ptof()" that converts packed-decimal to floating-point;  wrote it 10 =
years ago and have just been hauling it around since.  However, the =
converse function ("ftop()") seems to have disappeared in the mists of =
time.  It wouldn't be too hard to reconstruct, but the need hasn't =
arisen...

The "ptof()" source code comes with a pretty explanation of =
packed-decimal format, reprinted here:
    This routine converts the packed decimal in the input argument =
buffer
   into a double floating-point number.

    If these assumptions are incorrect, then this routine won't work!

          1. each 4-bit "nibble" in the packed decimal field contains a
             decimal digit in hex...

          2. the decimal digits are ordered from right to left when
             scanning from the lowest order digit to the highest...

          3. the "sign" nibble is the rightmost nibble in the packed
             decimal field...

          4. if the "sign" nibble is 0xA, 0xC, or 0xE, then the packed
             decimal's value is positive...

          5. if the "sign" nibble is 0xB, 0xD, or 0xF, then the packed
             decimal's value is negative...

          6. the actual byte width of the field is:

                  if (decimal width is an "odd" number then
                          (decimal width + 1) / 2)
                  else
                          (decimal width / 2) + 1

          7. the "sign" nibble is ALWAYS the rightmost nibble

    This is a diagram of a packed decimal field defined "DEC(9,5)" in
    Cobol:

       0       1       2       3       4       5   byte offset
       |---+---|---+---|---+---|---+---|---+---|
       |   |   |   |   |   |   |   |   |   |   |

          0x12    0x34    0x56    0x78    0x9B     hex value of each =
byte

       0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xB    hex value of each =
nibble
                                            ^
                                            sign =3D 0xB means =
"negative"

   This packed decimal field contains the value "-1234.56789", because
   it's format specification (i.e "DEC(9,5)") specifies a total field
   width of nine digits, five of which are to the right of the decimal
   point, and the sign is "0xB", which means it's a negative number...
Just recently, I had the dubious pleasure of writing PACKED2NUMBER and =
NUMBER2PACKED functions in PL/SQL.  These took packed-decimal numbers as =
input (in RAW format) and returned a NUMBER and vice-versa...

I haven't posted them, but I'd be glad to if you need them...
  ----- Original Message -----=20
  From: Brooks, Russ=20
  To: Multiple recipients of list ORACLE-L=20
  Sent: Wednesday, October 09, 2002 1:09 PM
  Subject: Packed decimal


  Hi,
    Is there any way to identify values in a field, defined in Oracle as =
number(11,2), with a packed decimal format?  Or to update the field with =
packed decimal values?

  Thanks,
  Russ

------=_NextPart_000_034B_01C2704C.8B7B6360
Content-Type: text/html;
 charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2719.2200" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>SQL*Loader understands how to translate =
PACKED and=20
ZONED DECIMAL format;&nbsp; pretty sure that PRO*Cobol does as well, =
though I=20
don't do Cobol...</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>If you're interested in conversion =
routines, I've a=20
"C" function named "ptof()" that converts packed-decimal to=20
floating-point;&nbsp; wrote it 10 years ago and have just been hauling =
it around=20
since.&nbsp; However, the converse function ("ftop()") seems to have =
disappeared=20
in the mists of time.&nbsp; It wouldn't be too hard to reconstruct, but =
the need=20
hasn't arisen...</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>The "ptof()" source code comes with a =
pretty=20
explanation of packed-decimal format, reprinted here:</FONT></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
  <DIV><FONT face=3DArial size=3D2>&nbsp; <FONT face=3DCourier>This =
routine converts=20
  the packed decimal in the input argument buffer</FONT></FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;into a double floating-point=20
  number.</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp; If these assumptions are =
incorrect, then=20
  this routine won't work!</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.=20
  each 4-bit "nibble" in the packed decimal field contains =
a</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
decimal=20
  digit in hex...</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.=20
  the decimal digits are ordered from right to left when</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
scanning=20
  from the lowest order digit to the highest...</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.=20
  the "sign" nibble is the rightmost nibble in the packed</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
decimal=20
  field...</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.=20
  if the "sign" nibble is 0xA, 0xC, or 0xE, then the packed</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
decimal's=20
  value is positive...</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.=20
  if the "sign" nibble is 0xB, 0xD, or 0xF, then the packed</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
decimal's=20
  value is negative...</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.=20
  the actual byte width of the field is:</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier=20
  =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;=20
  if (decimal width is an "odd" number then</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;=20
  (decimal width + 1) / 2)</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;=20
  else</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;=20
  (decimal width / 2) + 1</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.=20
  the "sign" nibble is ALWAYS the rightmost nibble</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp; This is a diagram of a =
packed decimal=20
  field defined "DEC(9,5)" in</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp; Cobol:</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;=20
  0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
  2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
  4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp; byte =
offset</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;=20
  |---+---|---+---|---+---|---+---|---+---|</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;&nbsp;&nbsp;&nbsp; =
|&nbsp;&nbsp;=20
  |&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp;=20
  |&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp; |</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
  0x12&nbsp;&nbsp;&nbsp; 0x34&nbsp;&nbsp;&nbsp; 0x56&nbsp;&nbsp;&nbsp;=20
  0x78&nbsp;&nbsp;&nbsp; 0x9B&nbsp;&nbsp;&nbsp;&nbsp; hex value of each=20
  byte</FONT></DIV>
  <DIV><FONT face=3DCourier></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;&nbsp;&nbsp;&nbsp; 0x1 0x2 =
0x3 0x4 0x5=20
  0x6 0x7 0x8 0x9 0xB&nbsp;&nbsp;&nbsp; hex value of each =
nibble</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
  ^</FONT></DIV>
  <DIV><FONT face=3DCourier=20
  =
size=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
  sign =3D 0xB means "negative"</FONT></DIV>
  <DIV><FONT face=3DCourier></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;This packed decimal field =
contains the=20
  value "-1234.56789", because</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;it's format specification =
(i.e=20
  "DEC(9,5)") specifies a total field</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;width of nine digits, five of =
which are=20
  to the right of the decimal</FONT></DIV>
  <DIV><FONT face=3DCourier size=3D2>&nbsp;point, and the sign is "0xB", =
which means=20
  it's a negative number...</FONT></DIV></BLOCKQUOTE>
<DIV><FONT face=3DArial size=3D2>Just recently, I had the dubious =
pleasure of=20
writing PACKED2NUMBER and NUMBER2PACKED functions in PL/SQL.&nbsp; These =
took=20
packed-decimal numbers as input (in RAW format) and returned a NUMBER =
and=20
vice-versa...</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>I haven't posted them, but I'd be glad =
to&nbsp;if=20
you need them...</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
  <DIV style=3D"FONT: 10pt arial">----- Original Message ----- </DIV>
  <DIV=20
  style=3D"BACKGROUND: #e4e4e4; FONT: 10pt arial; font-color: =
black"><B>From:</B>=20
  <A title=3DRuss.Brooks@dayzim.com =
href=3D"mailto:Russ.Brooks@dayzim.com">Brooks,=20
  Russ</A> </DIV>
  <DIV style=3D"FONT: 10pt arial"><B>To:</B> <A =
title=3DORACLE-L@fatcity.com=20
  href=3D"mailto:ORACLE-L@fatcity.com">Multiple recipients of list =
ORACLE-L</A>=20
  </DIV>
  <DIV style=3D"FONT: 10pt arial"><B>Sent:</B> Wednesday, October 09, =
2002 1:09=20
  PM</DIV>
  <DIV style=3D"FONT: 10pt arial"><B>Subject:</B> Packed decimal</DIV>
  <DIV><FONT face=3DArial size=3D2></FONT><FONT face=3DArial =
size=3D2></FONT><BR></DIV>
  <DIV><SPAN class=3D328420418-09102002><FONT face=3DArial=20
  size=3D2>Hi,</FONT></SPAN></DIV>
  <DIV><SPAN class=3D328420418-09102002><FONT face=3DArial =
size=3D2>&nbsp; Is there=20
  any way to identify values in a field, defined in Oracle as =
number(11,2), with=20
  a packed decimal format?&nbsp; Or to update the field with packed =
decimal=20
  values?</FONT></SPAN></DIV>
  <DIV><SPAN class=3D328420418-09102002><FONT face=3DArial=20
  size=3D2></FONT></SPAN>&nbsp;</DIV>
  <DIV><SPAN class=3D328420418-09102002><FONT face=3DArial=20
  size=3D2>Thanks,</FONT></SPAN></DIV>
  <DIV><SPAN class=3D328420418-09102002><FONT face=3DArial=20
  size=3D2>Russ</FONT></SPAN></DIV></BLOCKQUOTE></BODY></HTML>

------=_NextPart_000_034B_01C2704C.8B7B6360--

-- 
Please see the official ORACLE-L FAQ: http://www.orafaq.com
-- 
Author: Tim Gorman
  INET: Tim@SageLogix.com

Fat City Network Services    -- 858-538-5051 http://www.fatcity.com
San Diego, California        -- Mailing list and web hosting services
---------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB ORACLE-L
(or the name of mailing list you want to be removed from).  You may
also send the HELP command for other information (like subscribing).

