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-CCYY (N4)
1 #WS-TEMP-INT (N4.2)
1 #WS-TEMP-REM (N4.2)

DIVIDE 4 INTO #WS-TEMP-CCYY GIVING #WS-TEMP-INT REMAINDER #WS-TEMP-REM

When we corrected Local variable definition as shown below then it worked as expected.
1 #WS-TEMP-CCYY (N4)
1 #WS-TEMP-INT (N4)
1 #WS-TEMP-REM (N4)

DIVIDE 4 INTO #WS-TEMP-CCYY GIVING #WS-TEMP-INT REMAINDER #WS-TEMP-REM

Clarification:
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 Remainder - Wikipedia
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
end-define
*
#operand3 := #operand1
repeat while #operand3 > #operand2
  #operand3 := #operand3 - #operand2
end-repeat
display #operand3 
end

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)
end-define
divide 1.2 into 4.3 giving #operand3 remainder #operand4
display #operand3 #operand4
end

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
if #n8 = MASK(YYYYMMDD)
   write "leap year"
else
   write "no leap year"
end-if

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: