为什么 Math.min() 比 Math.max() 大?

考虑如下代码:


  1. var min = Math.min();  
  2. var max = Math.max();  
  3. console.log(min < max); 

按照常规思路,这段代码应该输出 true,毕竟最小值应该小于最大值。但是当我们运行这段代码时,却神奇的输出了 false。

为什么会这样呢?

还得去查查 MDN 的相关文档。

The Math.min() function returns the smallest of zero or more numbers.

Math.min 的参数是 0 个或者多个。如果是多个参数很容易理解,返回参数中最小的。

如果是 0 个参数呢?文档中写到:

If no arguments are given, the result is Infinity.

If at least one of arguments cannot be converted to a number, theresult is NaN.

如果没有参数,则返回 Infinity。Infinity 是什么呢?Infinity 是 javascript 中全局对象的一个属性,在浏览器环境中就是window 对象的一个属性,表示无穷大。

而 Math.max() 没有传递参数时返回的是 -Infinity。因此 Math.min() 要比 Math.max() 大。

后续:

为什么很多人会有这种疑惑,是因为犯了想当然的错误——望文生义。Math.min() 作为一个函数,返回的并不是最小值;同理 Math.max() 返回的也不是最大值。他们返回的是参数的最大值和最小值,而我们却没有传递任何参数。

javascript 中数值的最大值和最小值常量分别是 Number.MAX_VALUE 和 Number.MIN_VALUE,在我电脑 V8 的运行结果是 1.7976931348623157e+308 和 5e-324。

这里也有一个坑,那就是 MIN_VALUE 并不是最小的数,而是绝对值最小的数,它是一个正数。而 Math.min() 的返回值比 Number.MAX_VALUE 还要大。

Math.min() 返回了 Infinity,这个值对应了 Number.POSITIVE_INFINITY 常量。Math.max() 返回了 -Infinity,这个值对应了 Number.NEGATIVE_INFINITY 常量。

就像数学里面那样,正无穷和负无穷并不是确切的数,只是集合里面的概念。我们可以使用 0 减去正无穷来得到负无穷:0 - Infinity =
-Infinity,或者通过 0 减去负无穷来得到正无穷:0 - (-Infinity) =
Infinity。但是我们把正无穷和负无穷相加却得不到 0,事实上我们得到的是 NaN。

当我们真正明白了 Math.min 和 Math.max 只是返回了所有参数的最大值,就很容易理解这个看似匪夷所思的结果了。

本来想查看 V8 的源码,但是搜索了一圈,也只找到了几个测试用例(文件: test/mjsunit/math-min-max.js):


  1. assertEquals(Infinity, Math.min());  
  2. assertEquals(1, Math.min(1));  
  3. assertEquals(1, Math.min(1, 2));  
  4. assertEquals(1, Math.min(2, 1));  
  5. assertEquals(1, Math.min(1, 2, 3));  
  6. assertEquals(1, Math.min(3, 2, 1));  
  7. assertEquals(1, Math.min(2, 3, 1)); 

从此测试用例中可以看出,Math.min() 确实返回了 Infinity。继续阅读此测试用例还会发现更有意思的事:


  1. assertEquals(-Infinity, Infinity / Math.min(-0, +0));  
  2. assertEquals(-Infinity, Infinity / Math.min(+0, -0));  
  3. assertEquals(-Infinity, Infinity / Math.min(+0, -0, 1)); 

对比下面的结果:


  1. assertEquals(Infinity, Infinity / Math.max(-0, +0));  
  2. assertEquals(Infinity, Infinity / Math.max(+0, -0));  
  3. assertEquals(Infinity, Infinity / Math.max(+0, -0, -1)); 

也就是说在 Math.min 和 Math.max 进行数值比较(javascript不分整型和浮点型)时,负零是小于正零的。

-0、+0、-Infinity、+Infinity、NaN 这几个概念就可以讲上一天一夜了,篇幅有限就不展开讲了,以后有时间再填坑。

言归正传,现在我们换个思路,试着从算法的角度去考虑最大值和最小值的问题。

我们如何求 N 个参数的最大值呢?为了描述简单我们使用数组(感谢 @f2er前端百科)


  1. var max = ___; 
  2. arr.forEach(function(n) { 
  3.     if(n > max) { 
  4.         max = n; 
  5.     } 
  6. }); 

如果是填空题,你会在空格处填什么呢?如此想来,这个返回值就很合理了。

--------------------------------

<del>本来以为是无参调用时返回了运算的幺元,后来细琢磨,好像没有什么关系,2333

对于运算集合 S 上的二元运算*,如果满足 a*x = x*a = x,则 a 是*运算的幺元。加法运算的幺元是 0,因为 0+x =
x+0 = x。乘法运算的幺元是 1,因为 1*x = x*1 = x。但是我们定义函数 add() 或者 mult()
函数,如果不传递参数时,返回幺元的话也是不合理的。</del>

作者:justjavac

来源:51CTO

时间: 2025-01-20 11:00:41

为什么 Math.min() 比 Math.max() 大?的相关文章

JavaScript使用Math.Min返回两个数中较小数的方法_javascript技巧

本文实例讲述了JavaScript使用Math.Min返回两个数中较小数的方法.分享给大家供大家参考.具体如下: 下面JavaScript通过Math.Min返回两个数中较小的那个 <!DOCTYPE html> <html> <body> <p id="demo"> Click the button to return the lowest number of 5 and 10. </p> <button onclic

Javascript四舍五入Math.round()与Math.pow()使用介绍_javascript技巧

复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Javascrip

Adobe 在 MAX 大会上发布的这些黑科技,使其股价暴涨近 10%

如同 Google I/O,苹果 WWDC,微软 Build 这样一年一度的开发者大会一样,Adobe 公司也会每年都举行一场属于数字创意人士的盛会,称为 Adobe Max.在这场盛会上,Adobe 往往会发布一些与创意有关的新产品和新技术,同时也会透露公司的未来发展策略. 自然,今年也毫不例外. Adobe Creative Cloud 的几个更新 在当地时间 10 月 18 日的大会主题演讲中,Adobe 公布了旗下创意云 Creative Cloud(简称 Adobe CC) 的几大产品

JavaScipt中的Math.ceil() 、Math.floor() 、Math.round() 三个函数的理解_基础知识

首先还是看看JavaScript: The Definitive Guide, 4th Edition中对三个函数的定义. Math.ceil(): round a number up Arguments: Any numeric value or expression Returns: The closest integer greater than or equal to x. ---------------------------------------------------------

Javascript Math.ceil()与Math.round()与Math.floor()区别

Math.ceil()向上舍入 1 2 3 alert(Math.ceil(20.1)) //输出 21 alert(Math.ceil(20.5)) //输出 21 alert(Math.ceil(20.9)) //输出 21  Math.round标准的四舍五入 1 2 3 alert(Math.round(20.1)) //输出 20 alert(Math.round(20.5)) //输出 21 alert(Math.round(20.9)) //输出 21  Math.floor()向

javascript对象之内置对象Math使用方法_基础知识

一.Math.min()和Math.max(),分别返回参数中的最小和最大值 例: alert(Math.min(1,2,3)) //输出 "1" alert(Math.max(1,2,3)) //输出 "3" 二.Math.abs(),返回参数的绝对值 例: alert(Math.abs(-1)) //输出 "1" 三.Math.random(),产生一个0到1的随机数 例: window.open("http://www.***.c

JS组件福利大放送 推荐12款好用的Bootstrap组件_javascript技巧

前言:之前分享过很多bootstrap常用组件,包括表格.表单验证.文件上传.复选下拉框.弹出框等.这段时间,博主又收藏了一些好用的组件(有些在项目中已经用起来了),经过两天的时间,已经整理出了一部分,本着"好东西要与人分享"的原则,今天还是来点福利,将博主收藏的东西分享出来,供需要的园友参考.组件大部分都是些开源组件,也有部分是博主自己在网上找到然后改写出来的效果,可能不尽如人意,有兴趣的且看看吧. 一.时间组件 bootstrap风格的时间组件非常多,你可以在github上面随便搜

C#怎么计算一列数组的平均值,这是我程序,求大神帮忙看一下,哪里有问题。

问题描述 我的数组中的数据是从dataGridView1控件中来的,数组就1列,数组中的数据都是3.35,3.54,3.56.....这样的.然后想把这个数据求一下平均值,然后显示到textBox2控件上去.string[]sample=newstring[dataGridView1.Rows.Count];for(inti=0;i<dataGridView1.Rows.Count;i++){sample[i]=dataGridView1.Rows[i].Cells[0].ToString();

JavaScript程序员应该知道的45个实用技巧

 在这篇文章中,我将分享一组JavaScript的技巧.窍门和最佳实践,这些都是JavaScript程序员应该知晓的,不管他们是使用在浏览器/引擎上,还是服务器端(SSJS--Service Side JavaScript)JavaScript解释器上 如你所知,JavaScript是世界上第一的编程语言,它是Web的语言,是移动混合应用(mobile hybrid apps)的语言(比如PhoneGap或者Appcelerator),是服务器端的语言(比如NodeJS或者Wakanda),并且