Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Anyone have an FS that can convert a decimal length to a (reduced) fractional equivalent

eric_pestyeric_pesty Member Posts: 2,396 PRO

I know people in the metric (most of) world are going to be like "huh?" but I'm trying to match a convention to build a part description parametrically…

I was hoping Pascoe's "variable to string" FS would do it but it doesn't include that function, which tells me it's not super trivial so I thought I would ask if anyone has some code I can (respectfully!) "steal" before I go on a coding adventure!

Comments

  • Caden_ArmstrongCaden_Armstrong Member Posts: 334 PRO

    The stack overflow thread on the topic is somewhat helpful resource if you want an "optimal" answer
    https://stackoverflow.com/questions/5124743/algorithm-for-simplifying-decimal-to-fractions

    Its not a trivial problem, but its a simpler problem if you are constrained to not just any fractions, but typical base 2 fractions ( 1/4, 1/8, 1/16 , etc)

    You could find the closest /32 fraction (or 64 or 128) and then find the highest common factor


    for (var i = 0; i < 101; i += 1) { var dec = i/50; var denom = 32; var modval = 1/32; var numer = round(dec/modval); // this is the numerator in a x/32 var factors = [2,4,8,16,32]; // find the equivalent fraction with a different base for (var factor in factors) { if(numer%factor == 0) { println( numer/factor ~"/"~(32/factor)); // the last option this produces is the best answer } } }
    www.smartbenchsoftware.com --- fs.place --- Renaissance
    Custom FeatureScript and Onshape Integrated Applications
  • eric_pestyeric_pesty Member Posts: 2,396 PRO

    Thanks @Caden_Armstrong ,

    Ended up writing something with some help from ChatGPT (for the algorithm part)…

    Seems to work and looks like this if anyone is wondering:

    FeatureScript 2780;
    import(path : "onshape/std/common.fs", version : "2780.0");
    
    annotation { "Feature Type Name" : "Decimal to Fraction", "Feature Type Description" : "Convert a decimal length to a fraction string" }
    export const DectoFrac = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "Decimal Length" }
            isLength(definition.decLength, LENGTH_BOUNDS);
            
            annotation { "Name" : "Smallerst Denom, eg: 16 for 1/16", "UIHint" : UIHint.REMEMBER_PREVIOUS_VALUE }
            isInteger(definition.precision, POSITIVE_COUNT_BOUNDS);
            annotation { "Name" : "Variable Name" }
            definition.varName is string;
            
                
        }
        {
            const decValue = definition.decLength/inch;
            const precision = definition.precision;
            var whole=floor(decValue);
            var frac = decValue - whole;
            
            var denominator= precision;
            var numerator = round(frac * denominator);
            
            println(whole~" "~numerator~" / "~denominator);
            
                
            if (numerator !=0)
            {
                var a=numerator;
                var b=denominator;
                var r=1;
                while (b!=0)
                {
                    r=a%b;
                    a=b;
                    b=r;
                }
                var GCD=a; 
                println(GCD);
                numerator= floor(numerator/GCD);
                denominator = floor (denominator/GCD);
                
            }
            else
            {
                denominator=1;
            }
            
            if (numerator==denominator)
            {
                
            whole += 1;
            numerator=0;
                
            }
            
            /*
            println(whole);
            println(numerator);
            println(denominator);
            */
            var theString;
            if (whole==0)
            {
             theString=numerator~"/"~denominator;
            }
            else
            {
                theString=whole~"-"~numerator~"/"~denominator;
            }
            
            setVariable(context, definition.varName, theString);
            
            // Define the function's action
        });
    
Sign In or Register to comment.