1

I'm trying to use Javascript to verify that user input is a valid monetary (dollars and cents) amount, with no more than two digits to the right of the decimal point.

Shifting left, then performing a modulo 1 fails because of inherent floating-point issues:

(parseFloat("19.99") * 100) % 1 // Returns 0.9999999999997726

I'm aware of the BigDecimal library, but I'm not sure that converting to BigDecimal and then doing the validation would be the right approach, since it could cover up invalid inputs as well as floating-point issues.

As it stands, my workaround is to test the raw (string) input against the following regex:

/^\d*((\.\d{0,2})?)$/

Is this sufficient to guarantee that the input is a valid float in currency format? And if not, is there a math-based way to do the validation?

4
  • are .7 and 7. allowed? Commented May 1, 2014 at 17:05
  • Yes, as are "7", "7.7" and "0.7" Commented May 1, 2014 at 17:07
  • (+(n).toFixed(2) == +n) Commented May 1, 2014 at 17:08
  • Dan, you mind making that a formal answer so I can mark it? Commented May 1, 2014 at 17:20

2 Answers 2

2

if you don't need to use RegExp, let JS's math do the heavy-lifting:

 var n=myInput.value;
 if(!n || +(+n || 0).toFixed(2) != +n) {  
   alert("real numbers only!"); 
   myInput.select(); 
 }

the validation routine part is made up and poor UX, but the math is solid and bullet-proof.

Sign up to request clarification or add additional context in comments.

2 Comments

Above will fail for n=0 at !n, no? (And let's not go into "is zero a real number :-))
@G.Stoynev I thought that was the desired behavior, but it's easy enough to handle that case if needed...
2

Your regex will also match empty input, which is not right.

Try this regex instead:

^(?=[^.])\d*(?:\.\d{0,2})?$

Working Demo

  • (?=[^.]) is a lookahead that will make sure at least one non-dot character is there in input to avoid matching empty string.

1 Comment

Matching "12." is desired functionality. I'll use the leading follow quantifier, though, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.