Re: Converting packed decimal to a char array

CRPence <[email protected]>
Newsgroups gmane.comp.lang.as400.c
Organization midrange.com
Message-ID <[email protected]>
On 17-Mar-2015 04:51 -0500, Jevgeni Astanovski wrote:
> Big-big thanks to Barbara and Tim.
>
> The result is:
>
> void printdec(void *A, int Len, int Prec)
> {
>    decimal(63,0) fulldec ;
>    int offset, bytes ;
>
>    bytes = (Len / 2) + 1;
>    offset = 32 - bytes;
>    fulldec = 0;
>    memcpy(((char *) &fulldec) + offset, A, bytes);
>    printf("%0*.*D(63,*)\n", (Len + 1), Prec, Prec, fulldec) ;
> }
>
> is exactly what I've been looking for.
>

   The original requirements were not explicit, but if the alluded 
requirement for ensuring left-pad with zeroes implies *also* that a 
consistent length\layout of all valid values is required, then the 
formatting chosen for the above printf() might not be appropriate.  That 
is because [excepting when Prec=0] both negative values and values of 
maximal digits will appear laid-out in storage differently than other 
values; i.e. all possible values would not align [with the decimal point 
in the same location] within a fixed-width column.

    Some Example values for three variations of P(l,p) to exhibit the 
results with the aforementioned formatting:

     P(09,2)       P(03,0)    P(06,6)
     -----------   ----       ---------
     9876543.21    0321       0.660000
     -9876543.21   -321       -0.660000
     0876543.21    0001       0.000006
     -876543.21    -001       -0.000006
     0000000.21    0000       0.000000
     -000000.21
     0000000.00

   The following formatting choices may be more appropriate, if 
alignment within a [report] column is desirable:

     printf("%0 #*.*D(63,*)\n", (Len + 2), Prec, Prec, fulldec) ;

     printf("%0+#*.*D(63,*)\n", (Len + 2), Prec, Prec, fulldec) ;


   To avoid printing the decimal point for a zero-precision packed BCD 
[noting: the #flag in the above printf() examples would effect], then 
the alternative formatting shown below might be more appropriate; again, 
to ensure alignment within storage\report-column:

  void printdec(void *A, int Len, int Prec)
  {
     decimal(63,0) fulldec ;
     int offset, bytes , fmtLn ;

     if (Prec) fmtLn=Len+2 ; // first byte is not a digit
     else      fmtLn=Len+1 ; // zero-precision: less one byte
     bytes = (Len / 2) + 1;
     offset = 32 - bytes;
     fulldec = 0D;
     memcpy(((char *) &fulldec) + offset, A, bytes);
     printf("%0 *.*D(63,*)\n", fmtLn, Prec, Prec, fulldec) ;
   //printf("%0+*.*D(63,*)\n", fmtLn, Prec, Prec, fulldec) ;
  }

    Some Example values for three variations of P(l,p) to exhibit the 
results using the [active\non-commented] format-string in the revised 
version of the printdec() included just above; if the version with the 
plus symbol [the commented version with the +flag] were to used instead, 
the first character as blank for positive values would be the 
plus-character instead of the blank:

     P(09,2)       P(03,0)    P(06,6)
     -----------   ----       ---------
      9876543.21    321        0.660000
     -9876543.21   -321       -0.660000
      0876543.21    001        0.000006
     -0876543.21   -001       -0.000006
      0000000.21    000        0.000000
     -0000000.21
      0000000.00

-- 
Regards, Chuck
-- 
This is the Bare Metal Programming IBM i (AS/400 and iSeries) (C400-L) mailing list
To post a message email: C400-L-Zwy7GipZuJhWk0Htik3J/[email protected]
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/c400-l
or email: C400-L-request-Zwy7GipZuJhWk0Htik3J/[email protected]
Before posting, please take a moment to review the archives
at http://archive.midrange.com/c400-l.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.