admin管理员组文章数量:1394593
I am trying to add two decimal numbers (arguments could be numbers or strings that are numbers before they are parsed) and pare the oute with the resultInput
. The problem is that the floating-point numbers cannot be represented accurately enough by the system. For example, 0.1 + 0.2 = 0.30000000000000004
. So, I am trying to use toFixed()
method to format a number using fixed-point notation. I am getting false
when I run the code. Not sure where I am getting it wrong. Let me know if you have any ideas.
function calc(firstNumber, secondNumber, operation, resultInput) {
let a = parseFloat(firstNumber); //Number()
let b = parseFloat(secondNumber); //Number()
let c;
let d = parseFloat(resultInput);
console.log(JSON.stringify(`value of d : ${d}`)); //"value of d : NaN"
switch (operation) {
case '+':
c = a + b;
break;
case '-':
c = a - b;
break;
case '*':
c = a * b;
break;
case '/':
if (b === 0 && 1 / b === -Infinity) {
r = Infinity;
} else {
r = a / b;
}
break;
default:
console.log(`Sorry, wrong operator: ${operation}.`);
}
console.log(JSON.stringify(`value of c: ${c}`)); // "value of c: 0.30000000000000004"
let f = +c.toFixed(1);
let e = +d.toFixed(1);
console.log(JSON.stringify(`value of f: ${f}`)); // "value of f: 0.3"
console.log(typeof f); //number
console.log(JSON.stringify(`value of d: ${d}`)); // "value of d: NaN"
console.log(typeof d); //number
console.log(JSON.stringify(`value of e: ${e}`)); // "value of e: NaN"
console.log(typeof e); //number
if (f !== e) return false;
// if (!Object.is(f, e)) return false;
return true;
}
console.log(calc('0.1', '0.2', '+', '0.3'));
I am trying to add two decimal numbers (arguments could be numbers or strings that are numbers before they are parsed) and pare the oute with the resultInput
. The problem is that the floating-point numbers cannot be represented accurately enough by the system. For example, 0.1 + 0.2 = 0.30000000000000004
. So, I am trying to use toFixed()
method to format a number using fixed-point notation. I am getting false
when I run the code. Not sure where I am getting it wrong. Let me know if you have any ideas.
function calc(firstNumber, secondNumber, operation, resultInput) {
let a = parseFloat(firstNumber); //Number()
let b = parseFloat(secondNumber); //Number()
let c;
let d = parseFloat(resultInput);
console.log(JSON.stringify(`value of d : ${d}`)); //"value of d : NaN"
switch (operation) {
case '+':
c = a + b;
break;
case '-':
c = a - b;
break;
case '*':
c = a * b;
break;
case '/':
if (b === 0 && 1 / b === -Infinity) {
r = Infinity;
} else {
r = a / b;
}
break;
default:
console.log(`Sorry, wrong operator: ${operation}.`);
}
console.log(JSON.stringify(`value of c: ${c}`)); // "value of c: 0.30000000000000004"
let f = +c.toFixed(1);
let e = +d.toFixed(1);
console.log(JSON.stringify(`value of f: ${f}`)); // "value of f: 0.3"
console.log(typeof f); //number
console.log(JSON.stringify(`value of d: ${d}`)); // "value of d: NaN"
console.log(typeof d); //number
console.log(JSON.stringify(`value of e: ${e}`)); // "value of e: NaN"
console.log(typeof e); //number
if (f !== e) return false;
// if (!Object.is(f, e)) return false;
return true;
}
console.log(calc('0.1', '0.2', '+', '0.3'));
Share
Improve this question
edited May 17, 2019 at 4:18
John John
asked May 17, 2019 at 0:23
John JohnJohn John
1,5004 gold badges22 silver badges45 bronze badges
9
-
.toFixed()
returns a string so you'll need to convert it back to a number.let f = parseFloat(c.toFixed(1));
– zer00ne Commented May 17, 2019 at 0:25 -
this is what I want. To pare two strings
"0.3" === "0.3" //true
. or I am missing something? – John John Commented May 17, 2019 at 0:28 - Don't wrap numbers with quotes they bee strings. Strings do not behave like numbers. – zer00ne Commented May 17, 2019 at 0:28
- I need them to be strings as inputs. This is the condition of the task I am trying to solve. – John John Commented May 17, 2019 at 0:30
-
1
You appear to have some invisible characters showing up in your
result
string. You may want to consider parsing and.toFixed
ingresult
as well to ensure accuracy – Hamms Commented May 17, 2019 at 0:39
3 Answers
Reset to default 4Rather than converting back and forth to/from strings, you can create a function that tests if two numbers are close enough to be called equal. You decide some small delta and if the numbers are at least that close, you call it good.
function almost(a, b, delta = 0.000001){
return Math.abs(a - b) < delta
}
// not really equal
console.log("equal?", 0.2 + 0.1 === 0.3)
// but good enough
console.log("close enough?", almost(0.2 + 0.1, 0.3))
I run your code several times and there is no problem with it. I just found that the '0.3'
that you posted, it has an special character that looks like 3
but its not 3
. So, when you want to run it on JS it will show an error. So your solution was correct. Check here.
function calc(firstNumber, secondNumber, operation, resultInput) {
let a = parseFloat(firstNumber);
let b = parseFloat(secondNumber);
let aux = parseFloat(resultInput);
let r;
switch (operation) {
case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
r = a * b;
break;
case '/':
if (b !== 0) {
r = a / b;
} else {
r = 0;
}
break;
default:
console.log(`Sorry, wrong operator: ${operation}.`);
}
return (+r.toFixed(1)) === (+aux.toFixed(1));
}
console.log(calc('0.1', '0.2', '+', '0.3'));
This is not an direct answer, but an explanation about toFixed()
and behavior of floating point numbers:
toFixed()
returns a text. One reason is, that generally no number exists, the can represent the result of toFixed()
. So use this function only for displaying, but not for calculating like here.
let f = +c.toFixed(1);
let e = +d.toFixed(1);
toPrecision(18)
is good to display all relevant digits of a number. Some examples:
(0.1).toPrecision(18) // => 0.100000000000000006
(0.2).toPrecision(18) // => 0.200000000000000011
(0.3).toPrecision(18) // => 0.299999999999999989
The examples explains, why 0.1+0.2
is not the same as 0.3
.
Same examples with toFixed(1)
:
(+(0.1).toFixed(1)).toPrecision(18) // => 0.100000000000000006
(+(0.2).toFixed(1)).toPrecision(18) // => 0.200000000000000011
(+(0.3).toFixed(1)).toPrecision(18) // => 0.299999999999999989
It changed nothing: toFixed(1)
formats the number, and the +
sign convert it back to the nearest existing number.
This is not a JavaScript issue, it is an issue of puter based floating points number using IEEE 754 (binary based numbers). Most hardware support this kind of floats.
In puter mathematics it is usual, to pare equality of floating point numbers by using absolute or relative delta values. Example for absolute delta:
function isEqual( num1, num2, epsilon )
{
return Math.abs( num1 - num2 ) <= epsilon;
}
isEqual( 0.1 + 0.2, 0.3, 1e-10 ) // => true
Databases support dataytpes like DECIMAL(5.1)
. Here 0.1+0.2 == 0.3
, because the use internally interger numbers and format only the output.
JavaScript example for currency with 2 fraction digits (euro,cent):
// scan user input:
cent = round( euro * 100 );
// adding cents:
cent3 = cent1 + cent2;
// print cents as euro
(cent/100).toFixed(2)+"€"
本文标签: Adding and comparing two decimal numbers in JavaScriptStack Overflow
版权声明:本文标题:Adding and comparing two decimal numbers in JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744095072a2590134.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论