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.