when i try "eval" function as eval ("020 * 05 + 05") it is returning 85 instead off 105. Can someone explain me why eval function behave like this? Also suggest any to overcome this problem.
-
2where are you getting the string to eval? if you have control of it, you'd save yourself a lot of trouble by correcting the number formatting. – lincolnk Mar 26 '10 at 14:19
5 Answers
Numeric constants that start with a zero (like "020") are interpreted as octal. That's true for C, C++, Java, Javascript, and most any other language with even a vague cosmetic relationship to C.
If for some reason you really, really need to use "eval()", and you've got these weird strings with bogus leading zeros on the numeric constants, you might try something like this:
var answer = eval(weirdString.replace(/\b0(\d+)\b/g, '$1'));
However I wish you would find a way around using "eval()" at all. (Note the comment below noting that the hack shown above will have problems with numbers containing fractional parts.)

- 405,095
- 59
- 585
- 614
-
2This works for one leading zero, however it also removes a zero in numbers like "0.001", it becomes "0.01". – M. Boeckx Apr 29 '15 at 09:28
-
@M.Boeckx good point! However my real hope is that nobody ends up actually having this problem :) – Pointy Apr 29 '15 at 13:17
-
I've found an answer in another topic which works absolutely great! http://stackoverflow.com/a/18082175/2164420 Having to use eval is indeed less then ideal, so this solution is just what we needed here. It automatically removes all leading zero's. – M. Boeckx Apr 29 '15 at 13:58
-
1I think this one is better, it keeps the decimals too (see @M.Boeckx). `var answer = eval(weirdString.replace(/\b0*((\d+\.\d+|\d+))\b/g, "$1"));` – Filip Cornelissen Feb 04 '16 at 15:00
Javascript treats numbers beginning with 0 as octal. You can either remove the leading 0's or use parseInt(yourNumber,10) to convert to base 10.

- 9,665
- 1
- 30
- 38
Here is a link describing how the ParseInt function works in JavaScript and hence the reason you are getting an unexpected result.

- 113,795
- 27
- 197
- 251
-
1That's useful, but the thing is if he's got those strings with complete expressions in them, parseInt() isn't going to help much by itself. This is one of those cases where I wish we could walk backwards twenty or thirty steps and find out where the OP has gone astray. – Pointy Mar 26 '10 at 14:07
Here's a cleaner, safer answer, assuming you've first ensured the expression doesn't have any illegal characters (in particular any lowercase z's) in it:
"blah blah arithmetic with leading 0's... 0012.0034 + 1200 - 05.0600*0 + 0"
.replace(/\b0+\b/g, 'z') // replace bare zeros with sentinel
.replace(/[1-9\.]0+/g, m => m.replace(/0/g, 'z')) // save these too
.replace(/0/g, '') // throw away the rest of the zeros
.replace(/z/g, '0') // turn sentinels back to zeros
HT Adam Wolf for reminding me of the term sentinel.

- 26,430
- 45
- 154
- 229
"100.0001".replace(/\b0(\d+)\b/g, '$1') ="100.1" so it dangerous solution
My solution:
function $calc(n, round, min, max) {
/// <summary>calculate expression from string</summary>
/// <param name="round" type="int">optional</param>
/// <param name="min" type="int">optional. minimum allowed value. if less return 0</param>
/// <param name="max" type="int">optional. maximum allowed value. if more return 0</param>
if (!n) return 0;
try {
n = Number(eval(n
.replace(/[^\d\.\-\+\*\/\(\)\e]/g, '')//remove illegal symbols
.replace(/^0+/, '')//replace first leading zero
.replace(/[^\d\.]+0+/g, function (s) {return s.substr(0, 1);}) //replace leading zero
));
} catch (e) { return 0; }
if (n == 0 || !isFinite(n)) return 0;
if (round != undefined) { var t = Math.pow(10, round); n = Math.round(n * t) / t; }
if (min != undefined && n < min) return 0;
if (max != undefined && n > max) return 0;
return n;
}
function is safe. if calculation is fail or NaN of infinite, return 0
$calc('0100.08-(0.01+00.04)')=100.03
$calc('0/0')=0 //NaN
$calc('1/3',2)=0.33 //round

- 140
- 1
- 7