Chrome 中的 Math.log2 精度已更改

2024-03-12

我编写了一个 JavaScript 程序,它根据元素的数量计算二叉树的深度。我的程序几个月来一直运行良好,但最近我发现在 Chrome 和 Firefox 中查看网页时存在差异。

特别是在 Firefox 上:

Math.log2(8) = 3

但现在在 Chrome 中:

Math.log2(8) = 2.9999999999999996

我的 JavaScript 程序最初是为了根据元素数量查找二叉树的深度而编写的,如下所示:

var tree_depth = Math.floor(Math.log2(n_elements)) + 1;

我对这个公式做了一个简单的修改,以便它在 Chrome 上仍然可以正常工作:

var epsilon = 1.e-5;
var tree_depth = Math.floor(Math.log2(n_elements) + epsilon) + 1;

我有两个问题:

  1. 有没有其他人注意到 Chrome 最近的精度发生了变化Math.log2?

  2. 还有比我上面添加 epsilon 更优雅的修改吗?


Note: Math.log2自实施以来实际上没有改变 在V8中。也许您记错了,或者您添加了一个垫片 在 Chrome 之前碰巧得到了这些特殊情况的正确结果 包括它自己的实现Math.log2.

另外,看来你应该使用Math.ceil(x)而不是Math.floor(x) + 1.

我该如何解决这个问题?

To avoid relying on Math.log or Math.log2 being accurate amongst different implementations of JavaScript (the algorithm used is implementation-defined), you can use bitwise operators if you have less than 232 elements in your binary tree. This obviously isn't the fastest way of doing this (this is only O(n)), but it's a relatively simple example:

function log2floor(x) {
  // match the behaviour of Math.floor(Math.log2(x)), change it if you like
  if (x === 0) return -Infinity;

  for (var i = 0; i < 32; ++i) {
    if (x >>> i === 1) return i;
  }
}

console.log(log2floor(36) + 1); // 6

How is Math.log2目前在不同浏览器中实现?

Chrome 中当前的实现是不准确的,因为它们依赖于乘以Math.log(x) by Math.LOG2E,使其容易受到舍入误差的影响(source https://code.google.com/p/v8/source/browse/trunk/src/math.js?r=24772#236):

// ES6 draft 09-27-13, section 20.2.2.22.
function MathLog2(x) {
  return MathLog(x) * 1.442695040888963407;  // log2(x) = log(x)/log(2).
}

如果您运行的是 Firefox,它要么使用本机log2函数(如果存在),或者如果不存在(例如在 Windows 上 https://stackoverflow.com/questions/758001/log2-not-found-in-my-math-h/766669#766669),使用与 Chrome 类似的实现(source https://github.com/mozilla/gecko-dev/blob/4bb9cac09b222a97c99e3be93419936d1e693d08/js/src/jsmath.cpp#L1028).

唯一的区别是,它们不是乘法,而是除法log(2)反而:

#if !HAVE_LOG2
double log2(double x)
{
    return log(x) / M_LN2;
}
#endif

乘法或除法:相差多少does它使?

测试除以之间的差异Math.LN2并乘以Math.LOG2E,我们可以使用以下测试:

function log2d(x) { return Math.log(x) / Math.LN2; }
function log2m(x) { return Math.log(x) * Math.LOG2E; }

// 2^1024 rounds to Infinity
for (var i = 0; i < 1024; ++i) {
  var resultD = log2d(Math.pow(2, i));
  var resultM = log2m(Math.pow(2, i));

  if (resultD !== i) console.log('log2d: expected ' + i + ', actual ' + resultD);
  if (resultM !== i) console.log('log2m: expected ' + i + ', actual ' + resultM);
}

Note that no matter which function you use, they still have floating point errors for certain values1. It just so happens that the floating point representation of log(2) is less than the actual value, resulting in a value higher than the actual value (while log2(e) is lower). This means that using log(2) will round down to the correct value for these special cases.

1: log(pow(2, 29)) / log(2) === 29.000000000000004

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Chrome 中的 Math.log2 精度已更改 的相关文章

  • 单击时获取元素的 id(php、jquery、ajax、javascript)

    抱歉 这是我的第一个项目 我学到了很多东西 因此 如果有人可以帮助我 我将不胜感激 我的项目中有这个侧边栏 其中包含 rss 链接 我必须使用 ajax 因此每次用户单击任何 rss 链接时 提要都会出现在屏幕上 这是我的侧边栏代码 div
  • 非常基本的 JS 编码,是否有 SoundManager2?

    我想在我的网站上包含一个具有以下属性的音频 可能的视频播放器 必须可通过 div 通过 CSS 设计样式 可以读取所有ID3信息 可以从数据库中提取文件 可能是 GoDaddy 的 Easy Database 无闪光 可转移至智能手机等 我
  • 使用浏览器内的 JS 数值求解三角方程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 给定变量值s v and h 并给定一个库 例如数字 js http www numericjs com index php我怎样才能用数
  • Javascript 自时间戳以来经过的时间

    我试图通过将其存储在变量中来 缓存 一些信息 如果 2 分钟过去了 我想获取 实时 值 调用 url 如果 2 分钟还没有过去 我想从变量中获取数据 我基本上想要的是 if time passed is less than 2 minute
  • 粉碎一个元素,向随机方向发送碎片

    我试图 粉碎 一个元素 例如 一个图像 并将其碎片朝随机方向飞行 当碎片到达目的地时 即x距离 以像素为单位 它们变成原始图像的较小版本 jQuery UI 的explode http api jqueryui com explode ef
  • 如何更改点击事件上的引导插入符指向方向

    我正在使用 2 3 2 引导程序 因为当我单击菜单按钮时 我可以更改插入符号图标的位置 我需要当我单击图标插入符号向上时 当您单击另一个项目时 插入符号返回到初始状态 这怎么可能 导航代码 div div class container d
  • 将其作为参数传递给 addEventListener()

    我想添加change一组复选框的事件 我如何访问this在我的事件函数中 这样当我执行事件时我可以访问复选框的值 这是我当前的代码 var checkboxes document getElementsByClassName cb Arra
  • 将 javascript 放在 header 之外有多糟糕?

    这个问题几乎已经说明了一切 我开始添加一些功能到我的周末项目 http www my clock net 对于我和几个朋友来说 这是一个小应用程序 因为我们是交换生 所以它对我们来说有点有用 但事情是这样的 我在 php 中执行此操作并使用
  • Facebook 登录无法在移动浏览器中使用

    我使用 react facebook login 在我的网站中实现了 facebook 登录module https github com keppelen react facebook login 我在 ComponentDidMount
  • Javascript“命名空间”和 jQuery AJAX

    我正在使用此处列出的建议 http www odetocode com articles 473 aspx http www odetocode com articles 473 aspx 使用模拟的JavaScript AJAX网络聊天系
  • 它们是“相同的”吗?代码大战

    这是完整的问题描述 给定两个数组 a 和 b 编写一个函数 comp a b Clojure 中的 compSame a b 来检查这两个数组是否具有 相同 元素以及相同的重数 这里 相同 意味着 b 中的元素是 a 平方中的元素 无论顺序
  • 如何更改 Vuetify 日历日期格式

    我正在尝试在以下 Vuetify 日历上启用输入事件 https github com vuetifyjs vuetify blob master packages docs src examples calendars complex e
  • 谷歌浏览器如何启动桌面应用程序?

    我真的不知道术语 所以我将从一个例子开始 如果我点击磁力链接 Google Chrome 会询问我是否要启动 torrent 客户端 我单击 确定 chrome 启动该应用程序 该应用程序根据链接执行一些操作 现在有办法查看应用程序如何从
  • 调用不带括号的 javascript 函数

    以下 renderChat 函数用于将消息和图像渲染到聊天板上 该函数内部还有另一个函数 var onComplete function 它完成创建列表元素并将其附加到聊天列表的所有工作 onComplete函数之后就只有这三行代码 img
  • 按钮导致页面重新加载

    我在我的页面上使用 html 和 jquery 在我的 html 中 我有一个按钮 单击该按钮将触发一个功能 当页面加载时 我调用文档准备中的主函数 这是我的代码 div div
  • 正则表达式获取两个方括号之间的数字

    您好 我需要使用正则表达式在 JavaScript 中获取两对方括号内的字符串 这是我的字符串 12 23 asd 到目前为止我尝试的是使用这种模式 d 我需要获得价值12使用正则表达式 您可以使用以下正则表达式 d 这将提取12 from
  • 限制线的长度

    我正在尝试画一条代表 弹弓 的线 并且希望它具有最大拉伸长度 在 p5 中 我在位置和位置之间画了一条线 line posA x posA y posB x posB y posA 是鼠标 x 和 y posB 是画布上圆的位置 我想要做的
  • onClick 事件适用于触摸屏设备上的触摸吗?

    我用过onclick我的网站上的活动 但是 当我在谷歌浏览器的开发人员模式移动视图中打开它时 触摸使用鼠标单击的元素没有任何反应 所以我的问题是 我还必须添加吗ontouch事件连同onclick事件或 onClick 事件适用于所有触摸屏
  • Firefox 和 Chrome 为 offsetTop 提供了不同的值

    我试图相对于输入字段定位一个跨度元素 让我们称之为 工具提示跨度 为此 我将工具提示跨度和输入字段包装在另一个跨度元素中 我们称之为 包装器跨度 该元素具有position relative 然后我设置position absolute在工
  • 保留对 React 状态变量的“引用”

    据我所知 Javascript 中没有指针 我有以下问题 但我想知道是否有一个解决方案让我无法解决 解决方案可能是普通的 Javascript 或者像 Context API 这样的 React js 钩子 useContext 或者更多

随机推荐

  • 您是否使用花括号来确定额外的范围? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用 Dapper 将存储过程中的字段映射到具有不同名称的类属性

    我从包含许多字段的 POJO 类中摘录了以下内容 public class Call public int Id get set public string Customer get set public int StatusId get
  • 如何忽略触发器中的错误并在 MS SQL Server 中执行相应操作

    我已经创建了 AFTER INSERT TRIGGER 现在如果在执行触发器时发生错误的话 它不应该影响触发表上的插入操作 总之 如果触发器中发生任何错误 则应忽略它 正如我用过的 BEGIN TRY END TRY BEGIN CATCH
  • 如何检查画布是否为空白? [复制]

    这个问题在这里已经有答案了 如何检查 HTML5 画布是否为空白或具有彩色像素 有没有快速的方法呢
  • std::future 和 clang 与 -stdlib=libstdc++

    以下程序无法与 clang 和 stdlib libstdc 链接 cat future cpp include
  • Python 多处理:进程的进度报告

    我的应用程序中有一些任务受 CPU 限制 并且我想使用多处理模块来使用多核处理器 我接受一个大任务 视频文件分析 并将其分成几个较小的任务 这些任务放入队列中并由工作进程完成 我想知道的是如何从这些工作进程向主进程报告进度 例如 我需要他们
  • 如何在PHP中获取客户端IP地址

    如何使用 PHP 获取客户端 IP 地址 我想保留通过 IP 地址登录我的网站的用户的记录 Answer recommended by PHP collectives php Collective 无论您做什么 请确保不要信任客户端发送的数
  • 不相关实体的 HQL 左连接

    我有 2 个实体 A and B 它们是相关的 但我不想将关系映射添加到 bean 我们如何使用之间的左外连接A and B使用 HQL 或标准 有一些解决方法可以解决这个问题 按照指示使用本机 SQLhere https stackove
  • 大型 WCF Web 服务请求因 (400) HTTP 错误请求而失败

    我遇到过这个明显常见的问题 但无法解决 如果我使用数组参数中相对较少的项目 我已测试最多 50 个 来调用 WCF Web 服务 则一切都很好 但是 如果我调用包含 500 个项目的 Web 服务 则会收到错误请求错误 有趣的是 我跑过Wi
  • 从 Bash 函数返回字典

    我想在 bash 中有一个函数 它创建一个字典作为局部变量 用一个元素填充字典 然后返回该字典作为输出 下面的代码正确吗 function Dictionary Builder local The Dictionary unset The
  • python 的 random.Random.seed 是如何工作的?

    我习惯打字random randrange 我会做一个from random import Random从现在开始发现错误 对于涉及程序生成的游戏 不 不是 Minecraft 克隆 p 我想保留几个不同的伪随机数生成器 一个用于世界的生成
  • 使用传单和 R 向 CircleMarkers 添加边框

    我想为 CircleMarkers 添加边框 我使用了以下代码 我找不到任何为笔画添加黑色边框的功能 pal lt colorNumeric palette RdYlBu domain city results ratio m lt lea
  • 合并一个数组中的两个 int 数组,且不重复

    我正在尝试将两个数组合并为一个而不重复 但我的代码无法正常工作 谁能建议如何解决这个问题 void unify int set A int size A int set B int size B int set C int size C i
  • Flurry Android Analytics 中未获取报告

    我已将 Flurry Analytics 集成到我的应用程序中 但无法获取 Flurry Dashboard 上的报告 但我按照 Flurry ReadMe PDF 中提到的方式集成了它 我使用 API 密钥实现了所需的所有代码 但不知道为
  • Rails Devise:登录后如何访问注册页面?

    我是 Rails 新手 我正在使用 devise gem 进行身份验证 首先 我通过默认注册页面添加一个新用户 例如 users sign up 然后 我按照以下说明将 sign up 页面设置为仅对符号用户可用 在过滤器之前设计阻止访问
  • 从我的 git 历史记录中删除 4 个提交

    我已经完成了一些提交并将它们推送到我的存储库中 然后我做了一个拉取请求 但我意识到有一些提交我不想出现在拉取请求中 它们看起来像这样 My commits look like this Correct HTML ab1c41c HTML e
  • 使用 WiX 创建语言选择对话框

    我使用 WiX 创建了一个多语言安装程序 我正在使用命令从命令行运行安装程序 msiexec i myinstaller msi TRANSFORMS 1041 并且工作正常 现在我已经使用引导程序创建了一个语言选择对话框 如何将所选语言传
  • 如何将Win32 HRESULT转换为int返回值?

    我正在用 C 编写一个 Windows 控制台应用程序 希望在成功时返回零 在失败时返回有意义的错误代码 即 S OK应该返回 0 并且E OUTOFMEMORY应该返回不同的返回值E FAIL等等 以下是一个好的方法吗 int wmain
  • 对于 std::string,复制初始化或直接初始化字符串文字更快吗?

    我有以下问题 应该遵循哪一项更好 为什么 string strMyString SampleString or string strMyString SampleString 我回答了here https stackoverflow com
  • Chrome 中的 Math.log2 精度已更改

    我编写了一个 JavaScript 程序 它根据元素的数量计算二叉树的深度 我的程序几个月来一直运行良好 但最近我发现在 Chrome 和 Firefox 中查看网页时存在差异 特别是在 Firefox 上 Math log2 8 3 但现