[Thread Prev][Thread Next][Index]

Re: [ferret_users] Function MOD : strange behavior



Hi,
Good thread. Thank you for the suggestions.  For the mask-definition question, here's another workaround.
 
yes? let lon180 = if longitude gt 180 then longitude-360 else longitude
yes? let mask = if lon180 gt -30 and lon180 lt 110 then 1

With whatever details about LT vs LE and  GT vs GE makes sense for your purposes.  Often we see observational data that's in (-180,180) and need to define a lon360 variable to do similar things. 

Ansley

On 8/27/2020 8:13 AM, Ryo Furue wrote:
Hi Olivier,

On Thu, Aug 27, 2020 at 4:51 PM Olivier Marti <olivier.marti@xxxxxxxxxxxx> wrote:
[ . . . ]
In computer, there is a difference between the "truncated division" (also called "symmetric") and the "floored division". Most langage implement the truncated division, when the math definition is the "floored division". And I agree that modulo and integer division should be compatible to get (m div n) * n + (m mod n) == m

In Fortran, MOD and MODULO functions have different behaviour with negative numbers !!

Yes, and MOD is symmetric about 0 and MODULO is floored (left-biased). If I remember correctly, MODULO was added to the standard much later than MOD.  As you say, the integer division in most computer languages is the symmetric version and therefore, the "correct" MOD function in such languages is the symmetric one.  (An exception I've found is Haskell.  This language uses the floored div and mod.)
 
I'm afraid Fortran misses a floored division (?)

Floored division isn't hard to implement.  In a pseudo code:

    fdiv(m,n) = floor(real(m) / real(n))
   ! I don't know what's correct when n < 0
   ! but I guess that m div (-n) == (-m) div n should be an identity.

But, while MODULO is clearly useful as you demonstrate, the floored division doesn't have much practical use in the application domain of Fortran.  That's why Fortran has added only MODULO to its standard while it didn't bother to standardize FDIV(m,n).

But my point is far more practical : I define some geographical areas with mask from latitude and longitude values. The work would be simpler if I could use a MOD (or MODULO or whatever) function that return a number in [0,360[, and not in ]-360,360[

We can build the MODULO function out of the MOD function:

let mod_m_360 = mod(m,360)
let modulo_m_360 = if mod_m_360 lt 0 then (360 + mod_m_360) else mod_m_360
 
this would be simpler if I could write :

LET m1 = IF lat LT 63 AND MODULO(lon,360)  LT 330 THEN 0 ELSE 1

A floored division could also be useful :-)

I agree.  I'd welcome MODULO, FLOOR, and CEILING.

Ryo


-- 
Ansley Manke
Science Data Integration Group
NOAA Pacific Marine Environmental Laboratory
7600 Sand Point Way NE
Seattle WA 98115

I am currently teleworking and am available Tue-Wed-Thu.

[Thread Prev][Thread Next][Index]
Contact Us
Dept of Commerce / NOAA / OAR / PMEL / Ferret

Privacy Policy | Disclaimer | Accessibility Statement