为什么 Google Chrome 改变背景不透明度?
Why does Google Chrome change background opacity?
我使用以下 CSS 规则设置 div
的背景颜色:
div {
background-color: rgba(96, 96, 96, .1);
}
在 Google Chrome v.42 的 'Computed' 选项卡的开发者工具中,我看到了这个结果 rgba(96, 96, 96, 0.0980392);
。我认为,它看起来像是一些 web-kit 优化...
在 FireFox v.36 中计算的背景颜色等于 rgba(96, 96, 96, 0.1)
我做了一个简单的 http://jsfiddle.net/sergfry/c7Lzf5v2/ 来展示它的实际效果。
那么,我可以防止 Google Chrome 中的不透明度发生变化吗?
谢谢!
正如 Quentin 所说,这是一个 IEEE 浮点数问题。
0.1
在技术上实际上并不存在于十进制浮点数中,仅仅是因为二进制的工作方式。
0.1
是十分之一,即 1/10。要以二进制显示,请使用二进制长除法将二进制 1 除以二进制 1010:
如您所见,0.1
的二进制是 0.0001100110011....0011
并且它会一直重复 0011
直到无穷大。
浏览器将选择最接近 0.1
的可用点并将其用作不透明度。有些会过去,有些会倒下。
FireFox 我猜它只是显示人类可读的版本,但实际上,它实际上使用的是计算机可用的浮点数。
举个例子:
body {
color: rgba(0,0,0,0.1); // actually 0.0980392
opacity: 0.1; // actually 0.100000001490116
}
完全相同的浮点数的两个完全不同的值。
这个浮点问题实际上可以在使用其他语言(例如 Javascript)的浏览器中的其他地方复制。 Javascript 数字始终是 64 位浮点数(我相信 CSS 也是)。这通常称为双精度浮点数。 PHP 也使用双精度浮点数。
64位浮点数如你所想,以64位存储,其中数字(小数)存储在0到51位,指数存储在52到62位,符号存储在63位.
这会引起问题,因为这意味着整数最多只能计算 15 个小数点,实际上最多只能计算 17 个小数点。
这意味着数字很容易四舍五入,或者可能存储不正确。
var x = 999999999999999; // x = 999999999999999
var y = 9999999999999999; // y = 10000000000000000
浮点运算也可能在很多地方不对齐。正如我上面所展示的;十进制的 0.1
不是实际的 0.1
而是 0.000110011...
等等。这意味着一些基础数学可能是完全错误的。
var x = 0.2 + 0.1; // x = 0.30000000000000004
您最终不得不混淆系统以获得您真正想要的号码。这可以通过 *
数字 10
然后除以得到您实际想要的结果来完成。
var x = (0.2 * 10 + 0.1 * 10) / 10; // x = 0.3
计算机浮点精度非常困难,当有多个不同的实现(或浏览器)试图尽最大努力提高速度并正确显示给定的信息时,更加困难。
关于浮点数以及 CSS 处理器(或我预期的 JS 计算可能相同)可能试图实现的目标,有很多不同的信息。
我使用以下 CSS 规则设置 div
的背景颜色:
div {
background-color: rgba(96, 96, 96, .1);
}
在 Google Chrome v.42 的 'Computed' 选项卡的开发者工具中,我看到了这个结果 rgba(96, 96, 96, 0.0980392);
。我认为,它看起来像是一些 web-kit 优化...
在 FireFox v.36 中计算的背景颜色等于 rgba(96, 96, 96, 0.1)
我做了一个简单的 http://jsfiddle.net/sergfry/c7Lzf5v2/ 来展示它的实际效果。
那么,我可以防止 Google Chrome 中的不透明度发生变化吗?
谢谢!
正如 Quentin 所说,这是一个 IEEE 浮点数问题。
0.1
在技术上实际上并不存在于十进制浮点数中,仅仅是因为二进制的工作方式。
0.1
是十分之一,即 1/10。要以二进制显示,请使用二进制长除法将二进制 1 除以二进制 1010:
如您所见,0.1
的二进制是 0.0001100110011....0011
并且它会一直重复 0011
直到无穷大。
浏览器将选择最接近 0.1
的可用点并将其用作不透明度。有些会过去,有些会倒下。
FireFox 我猜它只是显示人类可读的版本,但实际上,它实际上使用的是计算机可用的浮点数。
举个例子:
body {
color: rgba(0,0,0,0.1); // actually 0.0980392
opacity: 0.1; // actually 0.100000001490116
}
完全相同的浮点数的两个完全不同的值。
这个浮点问题实际上可以在使用其他语言(例如 Javascript)的浏览器中的其他地方复制。 Javascript 数字始终是 64 位浮点数(我相信 CSS 也是)。这通常称为双精度浮点数。 PHP 也使用双精度浮点数。
64位浮点数如你所想,以64位存储,其中数字(小数)存储在0到51位,指数存储在52到62位,符号存储在63位.
这会引起问题,因为这意味着整数最多只能计算 15 个小数点,实际上最多只能计算 17 个小数点。
这意味着数字很容易四舍五入,或者可能存储不正确。
var x = 999999999999999; // x = 999999999999999
var y = 9999999999999999; // y = 10000000000000000
浮点运算也可能在很多地方不对齐。正如我上面所展示的;十进制的 0.1
不是实际的 0.1
而是 0.000110011...
等等。这意味着一些基础数学可能是完全错误的。
var x = 0.2 + 0.1; // x = 0.30000000000000004
您最终不得不混淆系统以获得您真正想要的号码。这可以通过 *
数字 10
然后除以得到您实际想要的结果来完成。
var x = (0.2 * 10 + 0.1 * 10) / 10; // x = 0.3
计算机浮点精度非常困难,当有多个不同的实现(或浏览器)试图尽最大努力提高速度并正确显示给定的信息时,更加困难。
关于浮点数以及 CSS 处理器(或我预期的 JS 计算可能相同)可能试图实现的目标,有很多不同的信息。