Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 8 of 8
  1. #1
    New to the CF scene
    Join Date
    Jan 2013
    Posts
    4
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Question Regex to detect power of two fractions - behaving unexpectedly

    I have developed a JavaScript function to convert a decimal number of inches to a string displaying feet, inches, and fractional components - for example, 23.75 inches converts to 1' 11 3/4". (To my surprise, this appears not to be available 'pre-cooked' anywhere I can find using Google.)

    It will normally be used to convert to 'woodworking' fractions: halves, quarters, eighths, sixteenths, thirtyseconds, etc., where the denominator is a power of two. But I also want it to accept (subject to a warning and confirmation prompt) any other denominator.

    The function takes two parameters: the length in inches with optional decimal, and a precision (integer number) for the denominator to use for the fractional component (if any).

    I am attempting to detect whether the precision is a power of two, and prompt for confirmation if it isn't.

    The code snippet looks like this:
    Code:
    // Check if denominator is a power of two and warn if not
    	denom = precision.toString().match(/32|16|8|4|2/);
    	if(!denom) { // Denominator isn't regular woodworking fraction
    		ok = confirm("Fraction isn't the usual woodworking half, quarter, eighth, sixteenth etc. Did you mean this?",false);
    		if (!ok) {//code continues....
             }
    I would expect the Regex to trigger a confirmation prompt if the input precision is not 2, 4, 8, 16, or 32.

    But it returns a value of 2 (true) for precision = 12, and therefore doesn't trigger the alert, which I don't understand. It does trigger for precision = 3 or 6.

    The same expressionn in Java (not JavaScript) works as I expected, returning a match only if the string matches exactly one of the numbers in the Regex.

    Am I misunderstanging how the Regex match() function is supposed to work in JS? If so, why, and how can I otherwise detect and warn when the requested precision isn't a power of two? I could (but don't want to) code it explicitly to work out mathematically if precision is a power of two between 2 and 64, but would prefer to understand and use properly a Regex to detect this.

    Help welcome, if anyone can point me to a Regex tutorial specific to JavaScript, or explain what this regex is doing and why.

    Thanks.

    John McC
    Last edited by johnwmcc; 01-26-2013 at 07:59 PM.

  • #2
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,731
    Thanks
    202
    Thanked 2,508 Times in 2,486 Posts
    This may (or may not) help you:-

    Code:
    <html>
    <head>
    
    <script type="text/javascript">
    
    var roundTo = 16;  // round to nearest 1/roundTo;
    
    function fraction() {
    var decimal = document.getElementById('dec').value;
    if ((!/^\d*\.\d+$/g.test(decimal)) || (String(decimal).split('.')[1].length > 4)) {
    alert ("You must enter a decimal number (max 4 decimal digits)!");
    document.getElementById('dec').value = "";
    document.getElementById('dec').focus();
    return false;
    } 
    var whole = String(decimal).split('.')[0];
    decimal = parseFloat("." + String(decimal).split('.')[1]);
    var num = "1";
    for (var z=0; z<String(decimal).length-2; z++){
    num += "0";
    }
    decimal = parseInt(decimal*num);
    num = parseInt(num);
    for (z=2; z<decimal+1; z++) {
    if (decimal%z==0 && num%z==0) {
    decimal = decimal/z;
    num = num/z;
    z = 2;
    }
    }
    var result = ((whole==0)?"" : whole+" ") + decimal + "/" + num;
    
    alert ("Fractional value = " + result);
    
    var d = num/roundTo;
    var n = Math.round(decimal/d);
    alert ("Rounded to nearest 1/" + roundTo + " inch = " + ((whole==0)?"" : whole+" ") + n + "/" + roundTo + " inch");
    
    }
    
    </script>
    </head>
    
    <body>
    <input type="text" name="dec" id= "dec" size="6" >
    <button onclick = 'fraction();'>Change decimal to fraction</button>
    </body>
    </html>

    The first commandment was when Eve told Adam to eat the apple.
    - Pupil's answer to Catholic Elementary School test.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #3
    New to the CF scene
    Join Date
    Jan 2013
    Posts
    4
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Thank you for the suggestion. I can see the bit of code relevant to my issue as:
    Code:
    decimal = parseInt(decimal*num);
    num = parseInt(num);
    for (z=2; z<decimal+1; z++) {
    if (decimal%z==0 && num%z==0) {
    decimal = decimal/z;
    num = num/z;
    z = 2;
    }
    }
    I could use that, but in the interim have found an alternative which fits straight into my existing code.

    Instead of denom = string.match(/regex/); I have used the more explicit version:
    Code:
    denom = (precision == 2 || precision == 4 || precision == 8 || precision == 16 || precision == 32 || precision == 64);
    This just tests denom against the 6 values of precision that are common woodwork fractions.

    That solves my immediate problem and the code now works as expected.

    But I still don't understand what's happening in the original code, and would like to know for future reference.

    Incidentally, I also tried using variant regexs instead of the original /32|16|8|4|2/

    Neither of these work:
    /(32)|(16)|(8)|(4)|(2)/
    /(32){1}|(16){1}|(8){1}|(4){1}|(2){1}/

    and again I don't understand why not.

    John McC
    Last edited by johnwmcc; 01-26-2013 at 01:04 PM.

  • #4
    Senior Coder Logic Ali's Avatar
    Join Date
    Sep 2010
    Location
    London
    Posts
    1,028
    Thanks
    0
    Thanked 207 Times in 202 Posts
    Quote Originally Posted by johnwmcc View Post
    But it returns a value of 2 (true) for precision = 12, and therefore doesn't trigger the alert, which I don't understand.
    if you apply /32|16|8|4|2/ to "12" it is a match, because it contains 2.

    Use: /^(32|16|8|4|2)$/ (subject to having trimmed leading and trailing spaces).

  • Users who have thanked Logic Ali for this post:

    johnwmcc (01-26-2013)

  • #5
    New to the CF scene
    Join Date
    Jan 2013
    Posts
    4
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Smile

    I can see why this works, but didn't think to begin with I would need the ^ or $.

    Thank you.

    John McC

    PS. How can I mark this thread as 'Resolved'? I saw the choice when I started it, but can't find it now.
    Last edited by johnwmcc; 01-26-2013 at 01:50 PM.

  • #6
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,731
    Thanks
    202
    Thanked 2,508 Times in 2,486 Posts
    Quote Originally Posted by johnwmcc View Post
    I can see why this works, but didn't think to begin with I would need the ^ or $.

    Thank you.

    John McC

    PS. How can I mark this thread as 'Resolved'? I saw the choice when I started it, but can't find it now.
    Use the Edit button on your original post.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #7
    New to the CF scene
    Join Date
    Jan 2013
    Posts
    4
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Thanks. Will do.

    J

  • #8
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,184
    Thanks
    10
    Thanked 569 Times in 550 Posts
    Quote Originally Posted by Philip M View Post
    Use the Edit button on your original post.
    yeah, that's intuitive usability, NOT!

    We have a resolved feature?

    I've been here five years and haven't seen it.

    can somebody like a mod fix that? i mean, that's just piss-poor, and there's no reason at all that 10mins of elbow grease wouldn't save thousands of folks 10 seconds a day. The 10mins would be realized personally by the modifier within a year of daily use.

    the way it is, we DO NOT have a resolved feature, i don't care what anyone says; if the stupid user (like me) can't use it, it's broken, and needs fixed.

    sorry for straying off topic.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/1/19) IE7:0.2, IE8:6.7, IE11:7.4, IE9:3.8, IE10:4.4, FF:18.3, CH:43.6, SF:7.8, MOBILE:27.5


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •