我正在寻找一个在 Java 中工作的高效公式,它计算以下表达式:
(low + high) / 2
用于二分查找。 到目前为止,我一直在使用“低+(高-低)/2”和“高-(高-低)/2” 在某些情况下避免溢出和下溢,但不能同时避免两者。 现在我正在寻找一种有效的方法来执行此操作,它适用于任何整数(假设整数范围从 -MAX_INT - 1 到 MAX_INT)。
更新: 结合 Jander 和 Peter G. 的答案并进行了一段时间的实验,我得到了以下用于中间值元素及其直接邻居的公式:
最低中点(等于 floor((low + high)/2),例如 [2 3] -> 2, [2 4] -> 3, [-3 -2] -> -3)
mid = (low & high) + ((low ^ high) >> 1);
最高中点(等于 ceil((low + high)/2),例如 [2 3] -> 3, [2 4] -> 3, [-3 -2] -> -2)
low++;
mid = (low & high) + ((low ^ high) >> 1);
中点前(等于 floor((low + high - 1)/2)),例如[2 3] -> 2, [2 4] -> 2, [-7 -3] -> -6)
high--;
mid = (low & high) + ((low ^ high) >> 1);
中点后(等于 ceil((low + high + 1)/2)),例如[2 3] -> 3, [2 4] -> 4, [-7 -3] -> -4)
mid = (low & high) + ((low ^ high) >> 1) + 1;
或者,不用bitwise and (&) and or (|),稍微慢一点的代码(x >> 1可以换成floor(x/2)来获取按位运算符免费公式):
最左边的中点
halfLow = (low >> 1), halfHigh = (high >> 1);
mid = halfLow + halfHigh + ((low-2*halfLow + high-2*halfHigh) >> 1);
最右边的中点
low++
halfLow = (low >> 1), halfHigh = (high >> 1);
mid = halfLow + halfHigh + ((low-2*halfLow + high-2*halfHigh) >> 1);
中点前
high--;
halfLow = (low >> 1), halfHigh = (high >> 1);
mid = halfLow + halfHigh + ((low-2*halfLow + high-2*halfHigh) >> 1);
中点之后
halfLow = (low >> 1), halfHigh = (high >> 1);
mid = halfLow + halfHigh + ((low-2*halfLow + high-2*halfHigh) >> 1) + 1;
注意:上面的>>>运算符被认为是有符号的移位。
最佳答案
来自 http://aggregate.org/MAGIC/#Average%20of%20Integers :
(low & high) + ((low ^ high) / 2)
是两个无符号整数的防溢出平均值。
现在,这个技巧只适用于无符号整数。但是因为 ((a+x) + (b+x))/2 = (a+b)/2 + x,如果你有相同的无符号整数,你可以按如下方式捏造它位大小作为您的有符号整数:
unsigned int u_low = low + MAX_INT + 1;
unsigned int u_high = high + MAX_INT + 1;
unsigned int u_avg = (u_low & u_high) + (u_low ^ u_high)/2;
int avg = u_avg - MAX_INT - 1;
更新:经过进一步思考,即使您没有带符号的整数,这也会起作用。有符号和无符号整数在加法、减法和按位运算上是等价的。所以我们需要担心的是确保除法像无符号除法一样,我们可以通过使用移位并屏蔽掉最高位来实现。
low += MAX_INT + 1;
high += MAX_INT + 1;
avg = (low & high) + (((low ^ high) >> 1) & MAX_INT);
avg -= MAX_INT + 1;
(请注意,如果您使用的是 Java,则可以使用无符号移位 ... >>> 1,而不是 (... >> 1) & MAX_INT 。)
但是,我偶然发现了一个更简单的替代方案,但我还没有弄清楚它是如何工作的。无需通过 MAX_INT 调整数字或使用无符号变量或任何东西。很简单:
avg = (low & high) + ((low ^ high) >> 1);
在 -32768..32767 范围内测试了 16 位有符号整数 low 和 high 的所有组合,但尚未完全证明(无论如何由我)。
关于java - 安全整数中值公式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4844165/
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有, 也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg