No, I must not have done a good job explaining.

The only reason there was a factor of 100 in the calculation is that it

was there from the beginning. See the original calculation (way) below.

The only knowledge of the methods of the compiler you need to know is

how to effect the sequence of calculations. This is typically by

surrounding parts of the calculation by parentheses, as with COBOL.

Getting back to the "100", it doesn't matter what the values of the

numbers are. Any time you do division, you end up with a rounding (or

truncating) "error" because you have to stop calculating some time. If

you then multiply that result by a number, the rounding effect is also

multiplied, by the same number. In the example that started this whole

thread, the number was 100. That made the rounding effect 100 times as

large as it was in the intermediate result, and that made it effect the

final result.

If, on the other hand, you do all your multiplying first, and then the

division, you don't fall into this problem.

Multiplying, in contrast to division, results in a fixed set of decimal

places in the result, the sum of decimal places in both numbers. (If

you multiply a number with 2 decimal places by a number with 3 decimal

places, the result with have 5 decimal places; possibly not all

significant, depending on the numbers.)

Even if you round or truncate the result of a multiplication to fewer

places than the natural result, when you divide this result, the

rounding effect is also divided.

Let's try an example. But first, I feel that the "100" and "2600" in

the initial example can obscure rounding oddities, since so many zeros

show up. Lets pick some close but different numbers, say 127 and 2675

(or try it with any numbers).

If you do the divide first:

2675 / 3094 = 0.8645765 (by my $3 calculator)

127 * 0.8645765 = 109.80121 pretty good; rounds to 110 correctly

127 * 0.864576 = 109.80115 still pretty good

127 * 0.86457 = 109.80039 still OK

127 * 0.8645 = 109.7915 starting to slip

127 * 0.864 = 109.728 slipping further

127 * 0.86 = 109.22 rounds to 109; wrong result

127 * 0.8 = 101.6 the units digit is way off

This shows that, with these numbers and wanting a whole-number rounded

result, if the intermediate result is not carried to at least 3 decimal

places (0.864) you get the wrong result.

You can also easily see that if the multiplier (127) were larger (say

12,700), you would need more decimal places to not affect the rounded

whole number result -- 5 in this case. I see now I should have rounded

each decimal result above; if I had, I would have only needed 4 decimal

places to get the correct 12,700 * 0.8646 = 10,980.42, which rounds to

10,980.

If you do the multiply first:

2675 * 127 = 339,725

Since there were no decimal places in the numbers to be multiplied,

there are no decimal places in the result. But for grins, let's see how

may digits to the *left* of the decimal point we would have to lose to

affect the result.

339,725 / 3094 = 109.80122 which rounds to 110, the correct result

339,720 / 3094 = 109.79961 OK

339,700 / 3094 = 109.79314 still OK

339,000 / 3094 = 109.56690 questionable, depends on rounding method

330,000 / 3094 = 106.65804 which is wrong

If I had rounded the 4th line above to 340,000 / 3094, I would have

gotten 109.8901, which would have rounded to the correct 110, removing

the "questionable" comment.

If the multiplier had been the larger 12,700 as in the second divide

example, it still doesn't affect the result. I can lose up to 3 digits

to the *left* of the decimal place and not affect the final result.

So, when the multiply is done first, assumptions the compiler makes

about how many decimal places to use for an intermediate result don't

have the same effect as when the divide is done first. As long as the

multiply gives the correct result, the final result will be correct to

however many decimal places it is carried to.

That was the point I was trying to make.

Sorry for being so long-winded!

Quote:

> As you sad,

> "No, no, no!!!"

> You method only works if you HAPPEN to have a factor of 100 involved

> somewhere in the calculation. The way to handle this in COBOL is to

> >No, no, no!!!

snip...

> >The only reliable solution, that works no matter how the numbers are

> >defined, that works no matter what the values of the numbers are, and

> >that even works for other languages in addition to COBOL, is to

> >rearrange the calculation so that no division is done until the last

> >step.

> >In this case, that means changing the compute statement to read:

> > compute field-a rounded = (field-b * 100) / field-c

snip...

The original calculation:

Quote:

> >> compute field-a rounded = (field-b / field-c) * 100