为什么 Math.min() 比 Math.max() 大?(续)
2016-09-17 22:24
330 查看
昨天心血来潮写了一篇文章: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):
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.min 和 Math.max 进行数值比较(javascript不分整型和浮点型)时,负零是小于正零的。
-0、+0、-Infinity、+Infinity、NaN 这几个概念就可以讲上一天一夜了,篇幅有限就不展开讲了,以后有时间再填坑。
言归正传,现在我们换个思路,试着从算法的角度去考虑最大值和最小值的问题。
我们如何求 N 个参数的最大值呢?为了描述简单我们使用数组(感谢 @f2er前端百科)
var max = ___;
arr.forEach(function(n) {
if(n > max) {
max = n;
}
});
如果是填空题,你会在空格处填什么呢?如此想来,这个返回值就很合理了。
<del>本来以为是无参调用时返回了运算的幺元,后来细琢磨,好像没有什么关系,2333
对于运算集合 S 上的二元运算*,如果满足 a*x = x*a = x,则 a 是*运算的幺元。加法运算的幺元是 0,因为 0+x = x+0 = x。乘法运算的幺元是 1,因为 1*x = x*1 = x。但是我们定义函数 add() 或者 mult() 函数,如果不传递参数时,返回幺元的话也是不合理的。</del>
完。
赞赏
人赞赏
为什么很多人会有这种疑惑,是因为犯了想当然的错误——望文生义。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):
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.min 和 Math.max 进行数值比较(javascript不分整型和浮点型)时,负零是小于正零的。
-0、+0、-Infinity、+Infinity、NaN 这几个概念就可以讲上一天一夜了,篇幅有限就不展开讲了,以后有时间再填坑。
言归正传,现在我们换个思路,试着从算法的角度去考虑最大值和最小值的问题。
我们如何求 N 个参数的最大值呢?为了描述简单我们使用数组(感谢 @f2er前端百科)
var max = ___;
arr.forEach(function(n) {
if(n > max) {
max = n;
}
});
如果是填空题,你会在空格处填什么呢?如此想来,这个返回值就很合理了。
<del>本来以为是无参调用时返回了运算的幺元,后来细琢磨,好像没有什么关系,2333
对于运算集合 S 上的二元运算*,如果满足 a*x = x*a = x,则 a 是*运算的幺元。加法运算的幺元是 0,因为 0+x = x+0 = x。乘法运算的幺元是 1,因为 1*x = x*1 = x。但是我们定义函数 add() 或者 mult() 函数,如果不传递参数时,返回幺元的话也是不合理的。</del>
完。
赞赏
人赞赏
相关文章推荐
- Math.min() 为什么比 Math.max() 大?
- Math.min() 为什么比 Math.max() 大?
- STL_Algorithm5-math: random_shuffle, count, count_if, min_element, max_element, accumulate, for_each, transform
- JavaScript基础 生成任意随机小数的公式 Math.random() * (max - min) + min
- Math.min() / Math.max() 使用方法
- 使用Math.max和Math.min求数组的最大值和最小值
- 使用Math.max,Math.min获取数组中的最值
- 为什么我们要使用min-height和max-height样式属性?
- [底层] 为什么Integer.MIN_VALUE-1会等于Integer.MAX_VALUE
- js函数math.max()和math.min()函数的用法。用来限制最大最小值
- 使用Math.max,Math.min获取数组中的最值
- 为什么desc类型的索引不能被用与计算 min/max?
- 使用Math.max,Math.min获取数组中的最值实例
- js取最小最大值--Math.min()、math.max()
- 使用Math.max,Math.min获取数组中的最值
- 复习C#的方法Math.Max和Math.Min
- JavaScript基础 生成任意随机小数的公式 Math.random() * (max - min) + min
- max(min)-device-width和max(min)-width的区别
- sql server min max ,rownum 去除重复
- Tree, Min/Max/Balanced Depth