× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Thanks Scott,
I had a feeling it was something like that.
When you explained the "internal workings" of the operation, it made even more sense.

In your professional opinion, would it be better to use the %dec bif or the Eval(R) op-code.

Thanks,


 
Jeff Young
Sr. Programmer Analyst
IBM -e(logo) server Certified Systems Exper - iSeries Technical Solutions V5R2 
IBM  Certified Specialist- e(logo) server i5Series Technical Solutions Designer V5R3
IBM  Certified Specialist- e(logo)server i5Series Technical Solutions Implementer V5R3
  
 






________________________________
From: Scott Klement <rpg400-l@xxxxxxxxxxxxxxxx>
To: RPG programming on the IBM i / System i <rpg400-l@xxxxxxxxxxxx>
Sent: Monday, August 10, 2009 2:00:10 PM
Subject: Re: EVAL(H) Question

Hi Jeff,

By default, RPG uses something called "the Maximum Digits rule" for
decimal precision in the intermediate results of an expression.  Which
basically means that RPG needs to create temporary (under-the-covers)
variables for each step in calculating your expression.

First thing RPG has to do is take Srp_Value_Rate and divide it by 100.
So Srp_Value_Rate is a 5,2 field...  and 100 is a 3-digit field.  What's
the maximum possible digits to the left of the decimal place when
dividing a 5,2 by a 3,0 field?  still 3 digits, right?  There are no
decimal places in a 3,0 field, so division can't make the number higher.

So, since you can only have max 3-digits to the left of the decimal
place, the intermediate result will be 30,27 by default (30 digits with
27 decimal places).  And if Srp_Value_rate=40, that means you'll have

Srp_Value_Rate / 100
000.400000000000000000000000000

Now subtract that value from 1.  So you have a 1,0 field subtracting a
30,27 field?  Whats the max digits to the left of the decimal place?
it's one higher, because it could potentially overflow into a 4th digit
(-9 - -999 = -1018)  so you'll now have a 30,26 intermediate result

1 - (Srp_Value_Rate / 100)
000.600000000000000000000000000

This is silly because you don't *need* 26 decimal places here -- but RPG
thinks you do.  You really only need 2.

Now RPG needs to divide Current_Srp_Value by that intermediate result.
(Dividing by an intermediate result is often messy because RPG maxes out
the decimal places using the *MAXDIGITS style, which means the digits to
the left goes through the roof).

So you hae a 11,4 field divided by a 30,26 field.  How many maximum
digits to the left?  The maximum possible value of a 11,4 divided by a
30,26 would be yikes, 37 digits to the left of the decimal place?  That
won't fit into RPG's default 30 digit intermediate result fields, so
it'll eliminate all of the decimal places so that, at least the whole
numbers will be preserved.

current_base / (1 - (Srp_Value_Rate / 100))
000000000000000000000000000004

So that's what RPG is doing under the covers -- and is the reason why
you're having this problem.  At first glance, it might sound like
increasing the size of the intermediate field from 30 digits to 63
digits might help -- but it won't. Because the intermediate result of
the first two calculations will end up being 59 decimal places instead
of 26, thus creating the same problem (just in a larger field)

Personally, I'd solve the problem by doing this:

  eval(h) current_srp_value = Current_base
                        / %dec(1 - (Srp_Value_rate/100): 6: 2);

I've used the %DEC() BIF to control the size of the intermediate result.
  I've told RPG that the intermediate result of the first two steps of the
expression should be a 6,2 field -- that way, it won't calculate 26
decimal positions in the intermdiate result.

Then the final division results in a maximum of 13 digit intermediate
field, leaving 17 decimal positions, more than enough space for your
purposes, and the EVAL(H) then rounds it off to 2 decimal places, as
you'd expect.

That's the optimal solution -- but requires someone to sit down and
figure out what RPG is doing in order to know where to put the %DEC()
and know how big to make it.  So it requires a total geek like me. :) I
mean, really, who does that???

An easier solution is to specify EXPROPTS(*RESDECPOS) on the H-spec, or
the R extender on the EVAL.  In either case, that tells RPG not to drop
all of it's decimal places for it's intermediate result fields.
Instead, it'll force the intermediates to have as many decimal places as
the result.

eval(hr) current_srp_value = Current_base
                      / (1 - (Srp_Value_rate/100));

Have a lovely day.


Jeff Young wrote:
I have the following instruction in my program:
Eval(H) Current_SRP_Value =                   
    Current_Base / (1 - (SRP_Value_Rate / 100));

ATTR current_srp_value               
TYPE = PACKED(9,2), LENGTH = 5 BYTES 
ATTR current_base                     
TYPE = PACKED(11,4), LENGTH = 6 BYTES 
ATTR srp_value_rate                   
TYPE = PACKED(5,2), LENGTH = 3 BYTES 

EVAL SRP_Value_Rate       
SRP_VALUE_RATE = 040.00   
EVAL Current_Base         
CURRENT_BASE = 0000002.7938

The result being returned is 4.00.
When using a calculator, I get the value 4.6563333333333333.

I would expect the result to be 4.66.

Do I need to specify Eval(RH) to get the desired result?
I am on V5R4.

Thanks,
Jeff Young
Sr. Programmer Analyst
IBM -e(logo) server Certified Systems Exper - iSeries Technical Solutions V5R2
IBM  Certified Specialist- e(logo) server i5Series Technical Solutions Designer V5R3
IBM  Certified Specialist- e(logo)server i5Series Technical Solutions Implementer V5R3


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.