最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

node.js - Javascript decimal number comparison - Stack Overflow

programmeradmin0浏览0评论

I have two decimal numbers which only slightly differ at the last two decimal places eg. num1 = 1.12345 and num2 = 1.1234567 but doing a num1 === num2 check fails. What would be the best way in javascript to make the parison return true if there are only few extra decimal places in num2 pared to num1?

I know that num2 could be rounded by few decimal problems but therein arises the problem because I don't know in advance how many decimal places would be truncated in num1.

I have two decimal numbers which only slightly differ at the last two decimal places eg. num1 = 1.12345 and num2 = 1.1234567 but doing a num1 === num2 check fails. What would be the best way in javascript to make the parison return true if there are only few extra decimal places in num2 pared to num1?

I know that num2 could be rounded by few decimal problems but therein arises the problem because I don't know in advance how many decimal places would be truncated in num1.

Share Improve this question asked Jan 25, 2018 at 20:41 J KnowlesJ Knowles 1232 silver badges5 bronze badges 11
  • 1 you need to use toFixed – sumeet kumar Commented Jan 25, 2018 at 20:43
  • According to your logic, 1.23456 === 1.234567, but 1.23456 !== 1.234559? – TimoStaudinger Commented Jan 25, 2018 at 20:44
  • 1 00 and 67 differ "slightly"? You will need to define exactly what you want to happen before you can implement it. – Blorgbeard Commented Jan 25, 2018 at 20:44
  • 1 its not 00 and 67 its .0000000 and .0000067, thats pretty slight lol – Robbie Milejczak Commented Jan 25, 2018 at 20:45
  • 1 doesn't matter if .000000000000000000001 or .9999999999 – messerbill Commented Jan 25, 2018 at 20:45
 |  Show 6 more ments

4 Answers 4

Reset to default 2

There are two possible ways of doing this (that I am aware of). The first would be to use toFixed, to round your numbers. The second would be to present some precision factor, in order to define "slightly" (let's say slightly means "a difference less than 0.0001"). The functions that implement this are below

// a, b - the numbers you wish to pare, digits - the number of digits to round to
function pareUpTo(a, b, digits){
  a.toFixed(digits) === b.toFixed(digits) // first we round the numbers, then we pare them
}

// a, b - the numbers you wish to pare, precision- the amount to which the numbers are allowed to be different (let's say 0.01 for up to two digits)
function pareUpTo2(a, b, precision){
  Math.abs(a-b) < precision // we make the difference and check whether or not the difference is smaller than our desired precision (we use Math.abs to turn a negative difference into a positive one)
}

Your definition of === is not what === means, but I think I get what you are trying to do.

First, figure out which number is the shortest. Then, only pare the numbers by the amount of decimals in the shorter number.

I'm sure there is a cleaner way to do this, but I've drawn it out step-by-step to show the progression and to help make sense of the process.

function pare(x, y){
  // Convert both numbers to strings:
  var str1 = x.toString();
  var str2 = y.toString();

  // Get the shortest string
  var shortest = str1.length >= str2.length ? str2 : str1;
  console.log("Shorter number is: " + shortest); // Just for testing

  // Get number of decimals in shorter string
  var dec = shortest.indexOf(".");
  var numDecimals = shortest.length - dec - 1;

  // Only pare up to the least amount of decimals
  console.log(x + " and " + y + " equal? " + (str1.substr(0, numDecimals + dec + 1) === str2.substr(0, numDecimals + dec + 1)));
}

pare(1.12345, 1.1234567);
pare(1.22345, 1.1234567);
pare(-101.22345, -101.1234567);
pare(-101.12345, -101.1234567);

You can use toString and pare strings. This will solve the problem of not knowing in advance the number of digits.

    num1 = 1.12345 ;
    num2 = 1.1234567 ;
    str1 = num1.toString();
    str2= num2.toString();
    leng1 =str1.length;
    leng2=str2.length;
    minLength = Math.min(leng1 ,leng2);//ignore extra decimals
    str1 =str1.slice(0,minLength);
    str2 =str2.slice(0,minLength);
    console.log(str1 ===str2); //true

The way I would do this is to find the length of the "shorter" number, then truncate the "longer" number with this code from MDN:

function truncate(number, precision) {
    var factor = Math.pow(10, precision);
    // *shouldn't* introduce rounding errors
    return Math.floor(number * factor) / factor;
}

Where precision is the length of the shorter number. Which, you could get like this:

let num1 = 1.12345,
    num2 = 1.1234567;

// gets everything after the . as a string
let str1 = String.prototype.split.call(num1,'.')[1],
    str2 = String.prototype.split.call(num2,'.')[1];

let precision = Math.min(str1.length, str2.length);

Then, call the above function on both numbers and do your parison.

if(truncate(num1,precision) == truncate(num2,precision) //do stuff

I modified the function on the Math.round() page from MDN for this answer.

发布评论

评论列表(0)

  1. 暂无评论