× 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.



On 2011/12/8 2:57 PM, James Horn wrote:
I am changing some old code and there seems to be a difference in how the
divide statement works.

C YEAR DIV 4 AVEQTR
C LSTQTR SUB AVEQTR DIFQTR
C DIFQTR DIV AVEQTR RATIO
C EVAL RATIO = DIFQTR / AVEQTR
/FREE

AVEQTR = YEAR / 4;
DIFQTR = LSTQTR - AVEQTR;
RATIO = DIFQTR / AVEQTR;
RATIO = (LSTQTR - (AVEQTR)) / (AVEQTR) ;
RATIO = (LSTQTR - AVEQTR) / AVEQTR ;
RATIO = (LSTQTR - (YEAR /4)) / (YEAR /4) ;

When you use DIV and SUB, you are choosing the exact length and decimals for the temporary result value. When you use / and -, you are letting the compiler choose.

For addition, multiplication and subtraction, the sizes that the compiler picks for temporaries are related to the sizes of the operands. But for division, the size of the temporary is always the maximum number of digits. If the divisor of the division only has a few decimal places, then the division temporary only has a few integer places, and many decimal places, so the result is very accurate. But if the divisor of the division has many decimal places, then the division temporary has many integer places, and only a few decimal places, so the result is less accurate.

With your first five free-form assignments, you only have one division, so the sizes that the compiler is choosing for its temporaries works fine. The temporary for (LSTQTR - AVEQTR) / AVEQTR would be 63 digits, with lots of decimal places, probably over 30 decimals.

With your last free-form assignment, you are dividing by a division.
something / (YEAR / 4)
(YEAR / 4) has 63 digits and probably over 50 decimal places.
(something / (YEAR / 4))
has 63 digits, but because (YEAR / 4) has so many decimal places, the
compiler assume that (YEAR / 4) might be 0.000000000...001 (and dividing by that gives a huge number). So the compiler gives the temporary as many integer places as possible to avoid overflow. So the temporary used for
(something / (YEAR / 4))
probably doesn't have any decimal places at all.

As Brian said, it's a good idea to understand how the compiler determines the sizes of its temporaries. Working through your problem statement to figure out the sizes of the temporaries will be a useful exercise, since it's not too long.

And it's usually a good idea to use the (R) extender or EXPROPTS(*RESDECPOS), but you should understand how those work too, so it would be a good idea to work that problem statement both ways.

Besides using the (R) extender or EXPROPTS(*RESDECPOS), you can also control the size of the temporary result using %DEC, so you could make your EVAL work exactly the same as your DIV SUB DIV by using %DEC. (Or %DECH if you had been using half-adjust on your DIV SUB DIVs.)

But as you can see, this gets very ugly very fast.

RATIO = (LSTQTR - (YEAR /4)) / %DEC(YEAR /4 : 9 : 2) ;

Or instead of dividing YEAR by 4, you could multiply by .25, avoiding dividing by a division.

RATIO = (LSTQTR - (YEAR * .25)) / (YEAR * .25) ;

But it's also sometimes a good idea to use your own temporary and two statements, just for clarity. This might be easier to understand than the single statement.
AVEQTR = YEAR / 4;
RATIO = (LSTQTR - AVEQTR) / AVEQTR;

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

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.