JavaScript函数:获取两个数字之间的差异

72

我希望得到一个简单的Javascript函数,用来获取两个数之间的差值,使得foo(2, 3)foo(3,2)都能返回相同的差值1。

9个回答

174
var difference = function (a, b) { return Math.abs(a - b); }

8
更常用的语法:function diff(a,b){return Math.abs(a-b);}最好和简单的解决方案。 - Alxandr
2
然后 foo = difference,这样就完成了 :) - mykhal
为什么要将函数放在一个变量中? - Clement Herreman
3
克莱门特·赫尔曼(Clement Herreman)说:“这是另一回事了。这种'变幻'根本不必要,我只是想提供一个纯净的解决方案(在实际范围内正确定义函数)。”。 - mykhal
1
a = -1, b = 1... diff == 2 - Muhammad Umer

51

这里有一个简单的函数

function diff (num1, num2) {
  if (num1 > num2) {
    return num1 - num2
  } else {
    return num2 - num1
  }
}

作为一个更短的、一行的、单参数的、使用三元运算符的箭头函数

function diff (a, b) => a > b ? a - b : b - a

12
如果你想要找到一个负数和正数之间的差异,那么任何使用绝对值函数的解决方案都会提供不正确的结果。因此,这是最佳解决方案。 - Tom Gullen
6
@Tom Gullen: Math.abs(3 - (-5)) 的结果是 8 ;) (翻译:@Tom Gullen: Math.abs(3 - (-5)) will return 8 ;)) - Niels van der Rest
1
@Jake,我完全同意 :) 我举这个例子是为了向声称使用Math.abs()在使用负数时会得到错误结果的Tom进行说明。但由于8是正确答案,这表明Math.abs()给出了正确的答案。 - Niels van der Rest
1
这是任何有符号数的解决方案。Math.abs() 不是完整的解决方案。 - S.M.Mousavi
@ChrisDeacy,Niels正在向Tom解释如何使用Math.abs()的解决方案仍然可以返回正确的答案,例如3,-5的结果为8。他正在阐述与您试图表达的完全相同的观点... - Gust van de Wal
显示剩余6条评论

23
似乎很奇怪要定义一个全新的函数,只是为了在调用它时不用放置一个减号而使用逗号。
Math.abs(a - b);

vs

difference(a, b);

(使用不同的调用另一个你定义的函数来调用第一个代码示例的输出)。我会直接使用Math对象上内置的abs方法。

我同意。我喜欢将事物抽象化以实现可重用性,但在情况简单或只是内置的东西时,没有真正的好处。 - James

9
这意味着您想返回绝对值。
function foo(num1 , num2) {
   return Math.abs(num1-num2);
} 

4
function difference(n, m){
    return Math.abs(n - m)
}

1
我不明白为什么这个看似很普遍的问题会变得如此复杂,但我发现这里所有的答案在某些情况下都是错误的。
如果两个数字都在零的同侧,那么接受的答案是正确的,但如果数字不在零的同侧,则必须加上它们的绝对值,而不是相减。
function diff( x, y ) {

    if ( Math.sign( x ) === Math.sign( y ) ) {

        return Math.abs( x - y );

    } else {

        return Math.abs( x ) + Math.abs( y );

    };

};

diff( 2, 2 ) // 0
diff( -2, -2 ) // 0
diff( -2, 2 ) // 4
diff( 2, -2 ) // 4

在math.stackexchange.com上的解决方案:https://math.stackexchange.com/a/1893992


3
这是不必要的。Math.abs((-2) - 2)仍然会得出正确的答案。 - Mateusz Charytoniuk

0
在 TypeScript 中,如果有人感兴趣:
public getDiff(value: number, oldValue: number) {
    return value > oldValue ? value - oldValue : oldValue - value;
}

0

如果你在处理浮点数 - 上面答案的陷阱就在于数学计算。

例如

> 0.1 + 0.2
0.30000000000000004

在编程计算中,你可以使用类似这样的技巧:

total = parseFloat((total + parseFloat(difference.toFixed(2))).toFixed(2))

0

定义了四个函数后,我做了一个小基准测试,出乎意料地

fn1 = (a,b)=>(a>b)?a-b:b-a;
fn2 = (a,b)=>{let c= a-b;return c>0?c:-c;}
fn3 = (a,b)=>Math.abs(a-b)
fn4 = (a,b)=>Math.max(a-b, b-a)


for(let fn of [ fn1, fn2, fn3, fn4])
 executionTime(()=>{console.log(fn);for(let i=0;i<1_000_000;i++)fn(500_000,i)})
 

 
 
 
 function executionTime(cb){//calculate performance
    const t0 = performance.now();
    cb();
    const t1 = performance.now();
    console.log(`cb took ${t1 - t0} milliseconds.`);
}

这里是100万次迭代的结果:

  1. cb花费了11.129999998956919毫秒。
  2. cb花费了53.420000011101365毫秒。
  3. cb花费了47.40000003948808毫秒。
  4. cb花费了48.20000007748604毫秒。

但不幸的是,这些都是虚假的结果,我的意思是逐个执行在控制台上的结果是:

  1. 6.9ms 11.7 7.0 4.4
  2. 7.5ms 4.4 6.4 4.5
  3. 7.8ms 5.1 6.2 6.8
  4. 3.9ms 6.3 5.2 5.2

我认为在循环时,每次迭代后垃圾收集器会进行清理,而其他函数正在尽力运行。当逐个执行时,fn2排名第二,使用额外变量(vm正在使用寄存器进行优化?)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接