Divide and Remainder

Hi all,

Initially we coded with bleow syntax where divide statement used to return the remainder in #WS-TEMP-REM. However we got always 0 in Remainder field and it looks like #WS-TEMP-INT defined as N4.2 causing problem.

1 #WS-TEMP-INT (N4.2)
1 #WS-TEMP-REM (N4.2)


When we corrected Local variable definition as shown below then it worked as expected.


As such Natural does not give any error on both the syntax but it behaved differently when job run .Does this mean that giving statement operand must be Numeric field with out decimal ?

What remainder do you expect if you divide 4 into a number when the result contains 2 decimals? All results will have a precision of 2 decimals in this case. So the remainder is always 0. That’s not a problem with Natural but a problem of mathematics.

If you divide 3 into 1 you will always have a remainder (with any number of possible decimals). That’s also not a speciality of Natural but mathematics.

The Natural Documentation says:

Let’s say, that #WS-TEMP-CCYY has a value of9.0. Natural would do the following:

  1. 9 / 4 = 2.25
  2. 2.25 * 4 = 9
  3. 9 - 9 = 0
  4. #WS-TEMP-REM is set to 0

So only the field #WS-TEMP-INT has to be N4 in your case.

Btw, if possible (and there probably aren’t many reasons why it shouldn’t be) avoid using N-fields in computations, NATURAL will have to convert it back and forth as it isn’t possible to do any arithmetic operations on N (display format) fields.

That’s exactly that what I have learned about dividing with remainder in primary shool! But it is much more sophisticated doing it with decimals! :wink:

I guess it’s not that easy. Please see http://en.wikipedia.org/wiki/Remainder#The_remainder_for_real_numbers
Maybe Venkatesan has to define his own definition of a remainder. May that way is suitable:

define data local
01 #operand1 (N10.2) init <9>   /* input
01 #operand2 (N10.2) init <4.2> /* input
01 #operand3 (N10.2)            /* output
#operand3 := #operand1
repeat while #operand3 > #operand2
  #operand3 := #operand3 - #operand2
display #operand3 

But beware of negative values in #operand2!!

Now I know: The result depends on the format of #operand3. Try this:

define data local
1 #operand3 (N1.0)  /* and try (N1.1) and (N1.2) here
1 #operand4 (N1.1)
divide 1.2 into 4.3 giving #operand3 remainder #operand4
display #operand3 #operand4

Thanks for your reply. As you said the format of #Operand3 decideds the results of #operand4. It worked for N1.0 format alone.

Anyway we have used another syntax ‘DIVIDE 4 INTO #WS-TEMP-CCYY REMAINDER #WS-TEMP-REM-N’ and we got expected result here.
In this case we don’t need to worry about format of #operand3 as we are not using.

But beware: the value of #WS-TEMP-CCYY is changed after the devide!

BTW: Now I realize, that you want to make a test for leap year…
Just try this:

#n8 := #WS-TEMP-CCYY * 10000 + 0229   /* February 29th
   write "leap year"
   write "no leap year"

Because the rules for calculating a leap year are a bit complexer then “DIVIDE 4 into”. For example 2000 is a leap year, but 1900 isn’t …

Exactly, but the more comlex rules you mentioned were only introduced with the Gregorian Calendar ( i.e. years >= 1582 or so). The above program classifies 600, 700, 1300, 1500 etc. as “no leap years”, when in fact they were: In Julian Calendar every year divisible by four without remainder is a leap year. So if one wants to be exact, one would have to check first if #ws-temp-ccyy is smaller than 1582, in which case the divisibility by four must be checked, or greater, in which case a test for 29 February can apply. :wink:

And, please, when was the Julian Calendar implemented ?

EDIT: All you never wanted to know about the Julian Calendar: