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)

2 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.

4 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.