LCM and GCD of floats

Hi everybody!

Is there a short syntax for calculating the least common multiple (LCM) and greatest common divisor (GCD) of floats (instead of explicitly multiply them by a 10 factor, executing the lcm or gcd and then dividing the result by the factor)?

Moreover, why it is possible to do this:

{SinOsc.ar(gcd(SinOsc.ar(0.3) * 20.0, 100.0) * 200 + 100) * 0.1}.play;

but it is not possible to do this?

gcd(11.1, 100.2)

ERROR: binary operator ‘gcd’ failed.
RECEIVER:
Float 100.200000 CCCCCCCD 40590CCC
ARGS:
Float 11.100000 33333333 40263333
nil

In binary, these are repeating fractions so the result can’t be computed exactly.

In one of my quarks (I think ddwCommon) I have a fuzzygcd method that will do it up to a precision that you specify.

fuzzygcd(11.1, 100.2, 0.0001)
-> 0.30000000000001  // typical float rounding error

EDIT: GCD on UGens doesn’t do what you think:

a = {
	var trig = Impulse.kr(0);
	Poll.kr(trig, gcd(DC.ar(11.1), DC.ar(100.2)));
	FreeSelf.kr(trig <= 0);
	Silent.ar(1)
}.play;

UGen(BinaryOpUGen): 1

– not the 0.3 you were perhaps expecting.

hjh

Thanks!

I am testing it here, the fuzzygcd only works on client side, right ?

For doing float gcd/lcm calculations on the server side the only way is to do the decimal change trick ?

That would require a C plugin, so you’re right, only on client side.

I guess you would have to scale the numbers up by some large factor so that an integer GCD is meaningful, then divide by the same factor.

hjh

1 Like