Midrange News for the IBM i Community


Posted by: Chris Proctor
Programmer Analyst
Columbia Sports Company
Portland, OR
Moving a 9.0 field to an 8.0 field???
has no ratings.
Published: 21 Dec 2011
Revised: 23 Jan 2013 - 3785 days ago
Last viewed on: 01 Jun 2023 (4974 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

Moving a 9.0 field to an 8.0 field??? Published by: Chris Proctor on 21 Dec 2011 view comments(5)

Good morning. A coworker is trying to put a 9.0 field into an 8.0 field in freeform and he gets the error about the receiving field not being large enough. He said that he doesn't care what's in the 9th position.

I suggested that maybe he could cast the 9.0 field somehow, to an 8.0 value in the move. Maybe something like this:

field80 = %dec(field90:8:0);

Is anything like this valid? 

Return to midrangenews.com home page.
Sort Ascend | Descend

COMMENTS

(Sign in to Post a Comment)
Posted by: neilrh
Premium member *
Jackson, MI
Comment on: Moving a 9.0 field to an 8.0 field???
Posted: 11 years 5 months 15 days 3 hours 36 minutes ago

You only get the error when the value won't fit, if the value is 099999999, then eval will work.

Lose the last digit:  Field80 = %div(Field90:10)

Lose the first digit: Field80 = %rem(Field90:100000000)

Posted by: DaleB
Premium member *
Reading, PA
Comment on: Moving a 9.0 field to an 8.0 field???
Posted: 11 years 5 months 15 days 20 minutes ago

That compiler message is a warning, not an error. It's perfectly valid to use one of these:

       Field80 = Field90;
       Field80 = %DEC(Field90:8:0);

They are more or less equivalent. The first tries to move a 9P0 into an 8P0, aligned on the decimal point. The second explicitly converts 9P0 to 8P0 aligned on the decimal point, then moves the result of that to 8P0. Either way, there's no runtime error if the value of Field90 fits in the 8P0. If you care about the overflow, you'd probably put it in a Monitor group, or do an If/Else.

You said you don't care, so you just want it to truncate the high order digit, like a fixed format Z-ADD, I'd probably use the %REM(Field90:100000000) as suggested by Neil.

There are other methods that might be cheaper than %REM. Without actually benchmarking it, I'll postulate that using a DS with overlay could be faster:

     DField90          S              9P 0
     DField80          S              8P 0
     D                 DS
     D Wrk9S0                         9S 0
     D  Wrk8S0                        8S 0 OVERLAY(Wrk9S0:2)
      /FREE
       Wrk9S0  = Field90; // convert packed to zoned
       Field80 = Wrk8S0;  // convert zoned to packed
      /END-FREE

%REM does a division to get the remainder. Converting packed to zoned, and zoned to packed only involves moving nybbles around, with no actual calculations.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Moving a 9.0 field to an 8.0 field???
Posted: 11 years 5 months 14 days 15 hours 49 minutes ago

At the end of the day "truncation" is different from trapping an error.

You can only use MOVE, Z-ADD to avoid the error when there is high-order truncation. Otherwise a MONITOR group can be used to trap the error, however you WILL loose all the digits, not just the high-order 1.

I do have a work around that I've published. Don't recall if it is here on MidrangeNews.com or in a previous life. I'll look around for it and either post it here, or post the link to it.

Posted by: DaleB
Premium member *
Reading, PA
Comment on: Moving a 9.0 field to an 8.0 field???
Posted: 11 years 5 months 14 days 6 hours 27 minutes ago
Edited: Thu, 22 Dec, 2011 at 08:35:00 (4183 days ago)

Come to think of it, even the truncation that happens with MOVE and Z-ADD is actually done by internally trapping the exception. Seem to remember reading several years ago that the internal exception processing imposes a performance penalty.

But you don't lose anything. If you put the straight Eval in a Monitor, either the straight Eval works or it doesn't. If you fall into the On-Error, you run the workaround code and "convert" Field90 in a different way.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Moving a 9.0 field to an 8.0 field???
Posted: 11 years 5 months 14 days 1 hours 20 minutes ago
Edited: Thu, 22 Dec, 2011 at 14:45:57 (4183 days ago)

FOUND IT!

The routine is TRUNCDEC

 

     P truncDec        b                   export
     D truncDec        pi            63p31
     D    val                        63p31 const
     D    digits                     10i 0 value
     D    decposParm                 10i 0 value options(*nopass)
     D decpos          s             10i 0 inz(0)
     D valString       s             70a
     D newString       s             70a
     D sign            s              1a   inz('+')
     D startPos        s             10i 0 inz(0)
      /free
         if %parms >= 3;
            decpos = decposParm;
         endif;
         if val < 0;
            sign = '-';
         endif;
         valString = %editc(%abs(val) : 'P');
         valString = %xlate(' ':'0':valString);
         startPos = %scan('.' : valString)
                  - (digits - decpos);
         newString = sign + %subst(valString : startPos : digits + 1);
         return %dec(newString : 63 : 31);
      /end-free
     P truncDec        e

 You call it with the original value and the target length and optional decimal positions and it copies the source to the target truncating any digits higher than the length specified on parameter 1. You can pass %LEN(target) and %DECPOS(target) if you like.