Modulo operation please

Could we please get a modulo operation in pulpscript? As far as I'm aware there is no easy way to calculate this using the 4 basic operations.

someVariable = 20
someVariable %= 8
// someVariable == 4
1 Like

Module does exist. It might be missing for a module combo assignment, but it appears to exist on its own. I used it to reduce my AI's ticking.

Screenshot_7916

Thanks for that Daniel, unfortunately, while giving no error somehow, that doesn't seem to do anything, the variable always remains 0

1 Like

Can you show your code? That would suggest a bug in PulpScript.

Considering the modulo is not documented, I would guess it's not actually implemented, but the code I am using is as follows:

on crank do
  distance += event.ra
  f = distance % 8
  tell 4,4 to
    frame f
  end
end

Oh wow, you are not kidding. Module passes the parser but always returns 0. My AI's randomization was hiding the fact AI tick ran every frame.

1 Like

I would also love a modulo operator. For now, here's how I'm handling it in my code:

on modulo do 
  while param1 >= param2 do
    param1 -= param2
  end

  result = param1
end
1 Like

You should be able to make a constant time formula using division and flooring. Say "round((x / y) - floor(x / y)) * y)" should equivalent to modulo, round just to be safe. It works because all numbers are floats in Pulp and thus never lose the remainder during division.

1 Like

This is great and I will be using this, but a built in modulo would be much better. I'm going to mark this as the solution for now though, this is the pulpscript I am using:

mod = x
mod /= y
mod -= floor mod
mod *= y

x being the dividend and y being the divisor, mod will contain the modulus (remainder)

3 Likes

Nice implementation. I should maybe caution that you do want a final "mod = round mod" if you intend to use any non-powers of two. In my experience you'll get clean divisions and multiplications provided y is a power of two. Once you start using non-powers of twos the IEEE floating point will start getting less precise and your final number might not be a precise integer.

Thanks, yeah I was already rounding my numbers before getting the remainder, but if you're using decimals then you will need the extra round

No what I mean is you need this:

mod = x
mod /= y
mod -= floor mod
mod *= y
mod = round mod

Otherwise the function will return wrong (not-integer) results for non-power of two Ys.

5 Likes

Did you mean to round the mod at the end there? Currently it's just going to overwrite mod with round y

Oh you're right, my code was wrong. I've fixed it. The issue the round tries to solve is that IEEE stores the mantissa, and a exponent. When you use a number which is a power of two only the exponent is set. Therefore division by power of two is just an subtraction to the exponent.

When you divide by a non-power of two both the exponent and mantissa must change, and that introduces imprecision that results in numbers like 4.999999 when you want 5.

Thanks for the discussion and solution on this all. I'll put my 2 cents in though as well and say a module operator would be cool to have in Pulp.