资讯专栏INFORMATION COLUMN

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

xiguadada / 2831人阅读

摘要:本来以为是无参调用时返回了运算的幺元,后来细琢磨,好像没有什么关系,对于运算集合上的二元运算,如果满足,则是运算的幺元。乘法运算的幺元是,因为。但是我们定义函数或者函数,如果不传递参数时,返回幺元的话也是不合理的。

昨天心血来潮写了一篇文章:为什么Math.min() 比 Math.max() 大?

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

javascript 中数值的最大值和最小值常量分别是 Number.MAX_VALUENumber.MIN_VALUE,在我电脑 V8 的运行结果是 1.7976931348623157e+3085e-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):

assertEquals(Infinity, Math.min()); 
assertEquals(1, Math.min(1)); 
assertEquals(1, Math.min(1, 2)); 
assertEquals(1, Math.min(2, 1)); 
assertEquals(1, Math.min(1, 2, 3)); 
assertEquals(1, Math.min(3, 2, 1)); 
assertEquals(1, Math.min(2, 3, 1)); 

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

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

对比下面的结果:

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

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

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

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

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

var max = ___;
arr.forEach(function(n) { 
    if(n > max) { 
        max = n; 
    }
});

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

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

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

完。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80390.html

相关文章

  • Math.min() 什么 Math.max()

    摘要:考虑如下代码按照常规思路,这段代码应该输出,毕竟最小值应该小于最大值。为什么会这样呢还得去查查的相关文档。是什么呢是中全局对象的一个属性,在浏览器环境中就是对象的一个属性,表示无穷大。继续阅读为什么比大续 考虑如下代码: var min = Math.min(); var max = Math.max(); console.log(min < max); 按照常规思路,这段代码应该输出...

    hyuan 评论0 收藏0
  • 164. Maximum Gap

    摘要:这个的长度是最小可能的最大差值。注意考虑和两个边界值也要加进去。 题目:Given an unsorted array, find the maximum difference between the successive elements in its sorted form. Try to solve it in linear time/space. Return 0 if the...

    EddieChan 评论0 收藏0
  • 怪异的JavaScript系列(三)

    摘要:本文的思想源自于在上的演讲。我收集这些例子的主要目的是将它们整理并清楚理解它们的原理。着主要是因为大括号也是函数定义语法的一部分。自从年双十一正式上线,累计处理了亿错误事件,得到了金山软件等众多知名用户的认可。 译者按: JavaScript有很多坑,经常一不小心就要写bug。 原文: What the f*ck JavaScript? 译者: Fundebug 为了保证可读性...

    XboxYan 评论0 收藏0
  • JavaScript数据结构与算法-Sort-(leetcode原题)

    摘要:说明你可以假设数组中所有元素都是非负整数,且数值在位有符号整数范围内。提示按奇偶排序数组给定一个非负整数数组,中一半整数是奇数,一半整数是偶数。对数组进行排序,以便当为奇数时,也是奇数当为偶数时,也是偶数。 原博客地址:https://finget.github.io/2019... 排序 showImg(https://segmentfault.com/img/remote/146...

    Hanks10100 评论0 收藏0
  • JavaScript中8个常见的陷阱

    摘要:然而,不会在年的基础上加,而只是表示年。闭包这是一个经典的面试题虽然期望输出,然而实际上却不会。因为第行的没有在正确的环境下执行。 译者按: 漫漫编程路,总有一些坑让你泪流满面。 原文: Who said javascript was easy ? 译者: Fundebug 为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。 这里我们针对JavaScri...

    doodlewind 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<