Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-26-2013, 12:11 PM   PM User | #1
johnwmcc
New to the CF scene

 
Join Date: Jan 2013
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
johnwmcc is an unknown quantity at this point
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..
johnwmcc is offline   Reply With Quote
Old 01-26-2013, 12:44 PM   PM User | #2
Philip M
Supreme Master coder!

 
Philip M's Avatar
 
Join Date: Jun 2002
Location: London, England
Posts: 17,036
Thanks: 197
Thanked 2,411 Times in 2,389 Posts
Philip M has a spectacular aura aboutPhilip M has a spectacular aura aboutPhilip M has a spectacular aura about
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.
Philip M is offline   Reply With Quote
Old 01-26-2013, 01:00 PM   PM User | #3
johnwmcc
New to the CF scene

 
Join Date: Jan 2013
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
johnwmcc is an unknown quantity at this point
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..
johnwmcc is offline   Reply With Quote
Old 01-26-2013, 01:37 PM   PM User | #4
Logic Ali
Regular Coder

 
Logic Ali's Avatar
 
Join Date: Sep 2010
Location: London
Posts: 959
Thanks: 0
Thanked 198 Times in 193 Posts
Logic Ali will become famous soon enoughLogic Ali will become famous soon enough
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).
Logic Ali is offline   Reply With Quote
Users who have thanked Logic Ali for this post:
johnwmcc (01-26-2013)
Old 01-26-2013, 01:47 PM   PM User | #5
johnwmcc
New to the CF scene

 
Join Date: Jan 2013
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
johnwmcc is an unknown quantity at this point
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..
johnwmcc is offline   Reply With Quote
Old 01-26-2013, 02:06 PM   PM User | #6
Philip M
Supreme Master coder!

 
Philip M's Avatar
 
Join Date: Jun 2002
Location: London, England
Posts: 17,036
Thanks: 197
Thanked 2,411 Times in 2,389 Posts
Philip M has a spectacular aura aboutPhilip M has a spectacular aura aboutPhilip M has a spectacular aura about
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.
Philip M is offline   Reply With Quote
Old 01-26-2013, 07:58 PM   PM User | #7
johnwmcc
New to the CF scene

 
Join Date: Jan 2013
Posts: 4
Thanks: 1
Thanked 0 Times in 0 Posts
johnwmcc is an unknown quantity at this point
Thanks. Will do.

J
johnwmcc is offline   Reply With Quote
Old 01-27-2013, 06:05 AM   PM User | #8
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
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 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is online now   Reply With Quote
Reply

Bookmarks

Tags
fraction, regex

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 02:59 AM.


Advertisement
Log in to turn off these ads.