Starsound.XYZ

长夜伴浪破晓梦 梦晓破浪伴夜长

科技爱好者文摘(2021年9月)

这里记录值得分享的科技内容,不定时更新。
一般收录笔者平时网上冲浪时遇见的感兴趣的文章/软件/资源。

文章

  1. 绝对值的计算并不简单

计算一个数的绝对值看起来似乎很简单:如果数字是负数,那么让它改变符号;否则,就让保持原样。
Java 中,它可能看起来像这样:

1
2
3
4
5
6
public static double abs(double value) {
if (value < 0) {
return -value;
}
return value;
}

即使对于初级面试问题,这似乎也太容易了。这里有什么陷阱吗?
IEEE-754 标准中,特别是在 Java 中,有两个零 +0.0-0.0
如果将 1.0 除以 +0.0-0.0 ,则会得到完全不同的答案 +Infinity-Infinity 。然而,在比较运算中, +0.0-0.0 是无法区分的。
因此,上面的实现不会删除 -0.0 输入的减号。这可能会导致意想不到的结果。例如:

1
2
3
4
double x = -0.0;
if (1 / abs(x) < 0) {
System.out.println("oops");
}

x 模数的倒数不能为负,无论 x 值是多少。但在这种情况下,它可以。
如果您有虐待狂的情绪,请让您的应聘者在面试中写出 abs 方法。当他们写出一种像文章开头那样的方法时,你可以问他们是否有值 x 使条件 1 / abs (x) < 0 为真。在这样的采访之后,就会有关于贵公司的传闻。
好的,我们发现了问题。现在,如何解决?
为了可靠地区分负零和正零,有一种 Double.compare 方法:

1
2
3
4
5
6
public static double abs(double value) {
if (value < 0 || Double.compare(value, -0.0) == 0) {
return -value;
}
return value;
}

这是解决这个问题的一种有效方法。然而,对于这样一个微不足道的操作,我们的方法变得非常慢。 Double.compare 实现并不是那么简单。它需要对正数进行两次额外比较,对 -0.0 进行三次比较,对 +0.0 进行多达四次比较。
我们可以少做点吗?事实证明,我们可以通过从 中减去它来将正零和负零变成正零 0.0

1
2
System.out.println(0.0-(-0.0)); // 0.0
System.out.println(0.0-(+0.0)); // 0.0

因此,我们可以通过以下方式重写实现:

1
2
3
4
5
6
public static double abs(double value) {
if (value <= 0) {
return 0.0 - value;
}
return value;
}

我们知道分支是不好的。如果 CPU 分支预测器的猜测不正确,则代价可能非常高。
现在我们考虑是否能降到零分支。
如果我们查看 IEEE-754 格式的双精度数的二进制表示,我们可以看到符号只是一个最高有效位。因此,我们只需要无条件地清除这个最重要的位。在此操作期间,其余数字不会更改。在这方面,小数比整数更简单,其中负数通过二进制补码变成正数。我们可以通过 & 使用正确掩码的操作清除最高有效位。此外,我们还需要将 double 类型数字重新解释为 long 类型并在操作后还原它(这可以通过 longBitsToDouble 方法实现):

1
2
3
4
public static double abs(double value) {
return Double.longBitsToDouble(
Double.doubleToRawLongBits(value) & 0x7fffffffffffffffL);
}

这个实现根本不包含分支,分析表明该方法在某些条件下的吞吐量增加了 10%。之前的单分支实现在 Java 标准库中已经存在多年,但在即将到来的 Java 18 中,改进版本已经提交。
然而,在许多情况下,这些改进并不意味着什么。这是因为 JIT 编译器可以使用适当的汇编指令(如果可用),而完全忽略 Java 代码。但多亏了它,我可以写一篇(希望如此!)有趣的文章。

文摘

  1. 浏览器标准被大公司左右

最近这些年,浏览器开发商(比如谷歌和苹果)从 W3C 手中夺取了网络标准的控制权。
网络标准正越来越多由大公司来决定,而不是由标准化组织 W3C 来决定。
大公司为了自己的业务,让浏览器的功能不断膨胀,目标是让 Web 网站做到原生应用可以做的一切,这是一个巨大的错误。
大公司明白,添加到 Web 的功能越多,浏览器之间的竞争就会越少!
谁能跟上谷歌推出新标准的脚步? Mozilla 不能,苹果不能,甚至微软也认输了,放弃自己开发浏览器引擎,直接采用了 Chromium 作为自家 Edge 浏览器的内核。
想象一下,现在有一家小公司试图从头开始编写一个 Web 浏览器。简直不可能!网络如此复杂,他别无选择,只能采用少数现有的浏览器引擎之一:ChromiumWebKitGecko
这就是现在的状况,浏览器市场的竞争正在越来越少。“每个人都必须采用 Chromium ,这正是谷歌的计划。
谁主导了浏览器引擎,谁就控制了互联网。即使 Web 标准是开放的,理论上允许任何人实现浏览器引擎。但是 Web 标准那么多、那么复杂,实际上没有人可以实现能与 Chromium 抗衡的浏览器引擎,那么这种开放也没有意义了。
现在的 Web 标准被大公司控制,已经沦为 ChromiumWebKitGecko 和它们各自怪癖的集合。以后怎么可能还会有新引擎?
如果没有新的人可以编写浏览器引擎,网络就不会是开放的。开放只是一种错觉。

来源:科技爱好者周刊(第 177 期):iPad 的真正用途

工具

  1. View Source
    一个 Web 小工具,输入网址,就可以高亮显示该网址的源码,非常好用。

言论

一家印度电力公司的高管告诉我,印度面临的最大问题将是缺电,电力需求以历史上从未有过的速度增长。

因为印度的夏天太热了,而且变得越来越热,印度的中产阶级也越来越多。印度家庭有钱以后,第一件要买的东西不是汽车、电脑或平板电视,而是一台空调。

《如何提早发现宏观趋势》