Hello and welcome to our community! Is this your first visit?
Enjoy an ad free experience by logging in. Not a member yet? Register.

# Thread: Regex to detect power of two fractions - behaving unexpectedly

1. ## 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

Code:
```<html>

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

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

• 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

• Originally Posted by johnwmcc
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)

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

• Originally Posted by johnwmcc
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.

• Thanks. Will do.

J

• Originally Posted by Philip M
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.

•