Phenomenon COMPUTE ROUNDED

Hello all!

The following code produces confusing results.

define data local
01 #n3 (n3)
end-define
*
compute rounded #n3 = 2 / 3 * 100
write 'result #1' #n3
*
compute rounded #n3 = 2 * 100 / 3
write 'result #2' #n3
*
compute #n3 = 2 / 3 * 100
write 'result #3' #n3
*
compute #n3 = 2 * 100 / 3
write 'result #4' #n3
*
end

The output is as follows:

result #1   60
result #2   67
result #3    0
result #4   66

I found an explanation here: http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat622win/pg/pg_furth_arithm_0650.htm#AO_Prec_Results

To be honest: I don’t understand result #1. I would understand 0, but I don’t understand 60.

If i read this i have to think back to Pentium FDIV Bug.
Q: How many Pentium designers does it take to screw in a light bulb?
A: .99995827903, but that’s close enough for nontechnical people. :lol:

Just my two cents

Well, I don’t think about a bug in this case. I read the documentation maybe four or five times and got an enlightment:

OK, so let’s take my compute #1:
Result field is available. Rd is 0, and Fd is also 0. But the rounded option increases the precision of the result by 1 digit. So internally, there is 1 digit after decimal point. So

2 / 3 = 0.6
0.6 * 100 = 60

My two cents: COMPUTE ROUNDED can be very dangerous…

COMPUTE can be very dangerous…

You should always keep in mind
Natural can not compute
This is because Natural tries to “optimize” intermediate results whereas normal cal-culators try to optimize the precision of the result. If you want exact results, you should do a two step computation: first use F8 as a resulting field format and then move the result to the desired resulting field (with or without ROUNDED option).

I suggest SAG to implement new commands:

result :=/n/ expression
result :~/n/ expression

The first will compute with intermediate results as precise as the underlying hardware is able to and cut the result to n decimals. the second will round the result to n decimals instead.

I decided to use “/n/” as this is also used in IF/AT BREAK and to avoid misunderstandings as an expression can not begin with “/”

I also decided not to use ROUNDED, as this disturbs the read flow of the source code. With COMPUTE/ASSIGN you can leave out the keyword, but with ROUNDED you also have to use the keyword!

Just my two cents!

While using (F8) for a result field will almost always give you the accuracy you need, there are still things to be wary about if precision is important to you. For example, the value 0.1 cannot be exactly represented by a field defined as (F8).

I agree !! And Cobol, Java, C++ also cannot compute :slight_smile:

Why? Because you have to give instructions to the programming languages. And without them, they can do nothing.
The very first instructions are the definitions of the variables, that have to be used for compu-tation according to your requirements. How accurate has to be computed? Accordingly you define the length, especially the number of digits after the decimal point.
Has to be rounded? What has to be rounded? Only the result of a computation? Or do you want to compute with rounded intermediate results? It depends on your instructions, whether an intermediate result is used or not.
For example:
DEFINE DATA LOCAL
1 #P1 (P4,4) INIT <1>
1 #P2 (P4,4) INIT <373>
1 #P3 (P4,4) INIT <9,4>
1 #I-RESULT (P4,4)
1 #RESULT (P4,2)
END-DEFINE
*
COMPUTE #I-RESULT = #P1 / #P2 * #P3
COMPUTE ROUNDED #RESULT = #I-RESULT
WRITE ‘result #1#RESULT
*
COMPUTE ROUNDED #RESULT = #P1 / #P2 * #P3
WRITE ‘result #2#RESULT
END

The output is (on mainframe Z/Os):
result #1 0,02
result #2 0,03

I say, when Natural executes your instructions correctly, it can compute!

You also said:

Do you rely on the result given by a cal-culator?

What is the exact result of this arithmetical expression: X = 2 / 29 * 29

Is X = 2 ?

The pocket cal-culator Casio SL-300LU computes: X = 1,9999995

The cal-culator integrated in Windows computes X = 2. But is this result correct?
First it computes: 2 / 29 = 0,068965517241379310344827586206897. Then you multiply this intermediate result with 29 and the result is 2.

But if you compute with the same cal-culator: 0,068965517241379310344827586206897 * 29 the result is 1,999999999999999999999999999974

So the result depends on whether you have computed with an intermediate result or not. But which result is correct (exact) in your opinion?

Regarding floating point variables I agree with Curtis Pew. The Natural documentation also gives a hint for using floating point variables:
“When an alphanumeric, unpacked numeric or packed numeric value is converted to floating-point format (for example, in an assignment operation), the representation has to be chan-ged, that is, a sum of powers of ten has to be converted to a sum of powers of two.
Consequently, only numbers that are representable as a finite sum of powers of two can be represented exactly; all other numbers can only be represented approximately.

Thus, the conversion of alphanumeric, unpacked numeric or packed numeric values to floa-ting-point values, and vice versa, can introduce small errors.”

Such a small error occurs in the following example (on mainframe/Z/Os):

DEFINE DATA LOCAL
1 #Q (P8,2) INIT <2>
1 #P (P8,2) INIT <50>
1 #F (F8)
1 #RES-1 (P8,2)
1 #RES-2 (P8,2)
1 #RES-3 (P8,2)
END-DEFINE
COMPUTE #RES-1 = (#Q / #P)
COMPUTE ROUNDED #RES-2 = (#Q / #P)
*
COMPUTE #F = (#Q / #P)
COMPUTE #RES-3 = #F
DISPLAY ‘result #1#RES-1 ‘result #2#RES-2 ‘result #3#RES-3 #F
END

The output is:

result #1 result #2 result #3 #F


    0,04         0,04         0,03 +4,000000000000000E-02

The floating point variable #F contains the right value, but after this value is assigned to #RES-3, the value 0,03 is a wrong result.
Under Natural for Windows the variable #RES-3 contains the correct value 0,04.

I had funny problems writing this posting:

First:: I had to define the variable #F wrong with ( F8 ). There has to be a blank between the characters 8 and ) because without a blank, this smiley 8) would be produced.

Second: You’ re not allowed to use the word “cal-culator” in this forum. When submitting my posting, I received this message:
“The word cal-culator is on our list of spam related words. Please refrain from posting this word”

Therefore there’s a hyphen beetween the characters l and c

That’s why I’m not very happy with Numeric → Float → Numeric conversion. But I guess a (N10.7)-Field is suitable for me.

Please use the code-Tags for this. Like that:

[code]
...
1 #f8 (F8)
...
[/code]

:shock: :?: :shock:

You can not use the word cal-culator (without the hyphen), because Natural is not able to cal-culate correctly, so why be able to write the “bad” word cal-culator correctly? :lol:

Besides putting it in a code block, you can check the “Disable Smilies in the post” box below the textbox where you typed your post.