Shop OBEX P1 Docs P2 Docs Learn Events
Spin modulo operator broken? — Parallax Forums

Spin modulo operator broken?

DrGaryDrGary Posts: 7
edited 2007-06-04 22:15 in Propeller 1
Is the modulo operator in Spin broken? It produces (arguably) incorrect results for negative numbers.

For example, I expect -5 // 24 to return 19 as it does in Ruby/Python. Instead, it returns -5.

There are actually a variety of definitions for modulo operations in various languages with respect to negative dividends. See this wikipedia entry for a list. It seems that the Spin // behavior has been carried over from Fortran, but some modern languages have adopted a definition more mathematically consistent. See this discussion.

BTW, the Propeller manual calls it a "modulus" operator. That's at variance with common CS/engineering usage of "modulo." Given the confusion surrounding the definition of the operator, perhaps "remainder" would be the most appropriate name.

Why do I expect -5 // 24 to return 19? It's simple. If it's 1am now, then 6 hours ago it was (1-6)//24 = 19 hours or 7pm. As another example, suppose you're doing week calculations with days numbered from Sunday=0. You expect that if today is Monday (1), then 3 days ago would be a Friday(5). (1-3)//7=5. But Spin returns -2. Yuk.

A work-around is to add the modulo divisor if the dividend is negative:

'' return x // y, assuming rounding toward -infinity, instead of the rounding toward 0 assumed by the current implementation of Spin
PRI  remainder(x,y)
  if x < 0
    return (x // y) + y
  return x // y         

Comments

  • whickerwhicker Posts: 749
    edited 2007-06-03 02:52
    By your own admission, there doesn't seem to be a standard definition for mod, but I feel your pain.

    I've seen industrial motion controllers do this, where if the position encoder spins backwards from zero, the position goes negative up to the max count (now the minimum count) of the encoder.

    After any sort of offset math (turn the valve on 50 degrees from this position), I had to be sure to call the correction function. Personally I called it "PositionModulus( )". Again it acted equivalent to your function.

    As annoying as this was for you, it isn't an uncommon thing for mod to do that.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-06-04 22:15
    You are correct the // operator has odd symmetry, so given the modern interpretation it is more accurately defined as the remainder.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
Sign In or Register to comment.