Calculating Fractions

bepislesnack's icon

Hey all,

I was just wondering if anyone knows of a good way to calculate fractions in Max? For instance, if I have the number 1.5, I want it represented as 3/2 (in two seperate number boxes).

Any help would be greatly appreciated!

Bruce Alexander's icon

Just print the two numbers instead of dividing them?

bepislesnack's icon

Ooh the problem is that I'm using quite large numbers (200ish - 600ish) that I want to be much smaller numbers - when I divide these numbers, I'm rounding to 1 decimal place, and I kinda want the fraction to be calculated after this rounding. Thanks anyway!

temp account's icon

here's a max patch:

Max Patch
Copy patch and select New From Clipboard in Max.
(edit, fixed a syntax error)
and here's some javascript code to make the patch work (copy the code, paste it into a text file and name it floatToFrac, then put it in the max search path):

autowatch = 1;

var middle_n;
var middle_d;
var error=0.0001;
outlets= 2;

function msg_float(x){
    float_to_fraction (x, error);
    }

function float_to_fraction (x, error)
{
    var condition= true;
    var n = Math.floor(x)
    x = x-n;
    if (x <= error){
        
        outlet( 1, 1);
        outlet (0,  n);
        return;
    }
    else {
        if (1 - error <= x){
             
            outlet( 1, 1);
            outlet (0,  n+1);
            return;
        }
    }

    //The lower fraction is 0/1
    var lower_n = 0;
    var lower_d = 1;
    //The upper fraction is 1/1
    var upper_n = 1;
    var upper_d = 1;
    while (condition){
        //The middle fraction is (lower_n + upper_n) / (lower_d + upper_d)
        middle_n = lower_n + upper_n;
        middle_d = lower_d + upper_d;
       //If x + error < middle
        if (middle_d * (x + error) < middle_n){
            // middle is our new upper
            upper_n = middle_n;
            upper_d = middle_d;
        }
        //Else If middle < x - error
        else{
             if(middle_n < (x - error) * middle_d){
                // middle is our new lower
                lower_n = middle_n;
                lower_d = middle_d;
            }
            //Else middle is our best fraction
            else {
                condition=false; 
            }        
        }
     }
    
    outlet (1, middle_d);
    outlet(0,  n * middle_d + middle_n);
}
vojko v's icon

Hi temp account,

I'm trying to make a M4L patch for microtonal chords so I can see what are the nearest just ratios around the notes.

Example:

Let's say the cent values of my chord are 0. 400. and 700. and I want it to show a list of just sonorities (like 4:5:6, the just major chord) that are available around the notes of the chord listed by the simplicity of the numbers in the fractions and the overall error.

Do you know how would I do that?

Floating Point's icon

You could try this patch as a starting point:

Max Patch
Copy patch and select New From Clipboard in Max.

note you need to change the js file floatToFrac
so that the error variable is a some sort of number that can accommodate fractions up to a certain level of complexity.
try something like:
var error=0.03333333333;
if the number is too small (like 0.0001) the patch wont be very useful
if the number is too big (like 0.125) the pitch ratios will be "quantized" to very large steps (greater than a semitone, and too far from your original pitches)
I'm sure it can be refined further

(was temp account)

Floating Point's icon

this patch is simpler:

Max Patch
Copy patch and select New From Clipboard in Max.

vojko v's icon

thanks a lot, will check it out

Alex Nelson's icon

I'm having trouble getting the js floattofrac working. I also don't really understand how to use it. What does the message coming from the output do? And what about the free-floating one?

Floating Point's icon

Just had a look at it and my old copy of the floatToFrac.js seems to work, but does not respond to changes in the error tolerance (don't know why). The outputs are the numerator and denominator of a fraction closest equivalent to the input float.

Max Patch
Copy patch and select New From Clipboard in Max.