首页 > 其他分享 >如何计算比给定数字大的2的幂数

如何计算比给定数字大的2的幂数

时间:2024-09-19 15:50:49浏览次数:9  
标签:0000 数字 16 int source 给定 幂数 源码 0001

举例

比如3,计算后得出4,比如6,计算后得出8,

这种根据人类最直观的想法,当然一下能看出来,因为我们会去估计大于这个数字的2^n方是多少,但是数字大了就不是人类该做的事情了

如果根据最简单的思维,从2的0次方开始,增加n值,一个个循环试过去,也可以找到这个值,但是效率显然很低,我从源码里找到了两种高效的计算方式:

第一种计算方法

   int tableSizeFor(int source) {
        int maxCapacity = 1 << 30;
        int n = source- 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= maxCapacity ) ? maxCapacity : n + 1;
    }

接下来分析一下这个过程:
假设所求数字source = 20,那么n = 19

n=19
0000 0000 0000 0000 0000 0000 0001 0011
n>>>1
0000 0000 0000 0000 0000 0000 0000 1001
n |= n >>> 1
0000 0000 0000 0000 0000 0000 0001 1011
n>>>2
0000 0000 0000 0000 0000 0000 0000 0110
n |= n >>> 2
0000 0000 0000 0000 0000 0000 0001 1111
n>>>4
0000 0000 0000 0000 0000 0000 0000 0001
n |= n >>> 4
0000 0000 0000 0000 0000 0000 0001 1111
n>>>8
0000 0000 0000 0000 0000 0000 0000 0000
n |= n >>> 8
0000 0000 0000 0000 0000 0000 0001 1111
n>>>16
0000 0000 0000 0000 0000 0000 0000 0000
n |= n >>> 16
0000 0000 0000 0000 0000 0000 0001 1111
(n < 0) ? 1 : (n >= maxCapacity ) ? maxCapacity : n + 1
0000 0000 0000 0000 0000 0000 0010 0000

最后算出的结果就是32,过程很清晰了,那这是一个什么原理呢,其实就是通过位移31次(1+2+4+8+16)以及或运算,把当前最高位下面的二进制都填满1,这样再加1以后就能得到比原先高一位的数字,这个算法不可谓不高明。不知道有没有同学能认出来这个算法是出自于哪一段源码的呢?

第二种计算方法

int tableSizeFor(int source) {
        int n = 1;
        if (source >>> 16 == 0) {
            n += 16;
            source <<= 16;
        }
        if (source >>> 24 == 0) {
            n += 8;
            source <<= 8;
        }
        if (source >>> 28 == 0) {
            n += 4;
            source <<= 4;
        }
        if (source >>> 30 == 0) {
            n += 2;
            source <<= 2;
        }
        n -= source >>> 31;
        return 1<<(32-n);
}

过程分析:
假设source = 20

source 
0000 0000 0000 0000 0000 0000 0001 0100

右移16位 等于0 --> n+=16=17
0000 0000 0000 0000 0000 0000 0000 0000

左移16位 source当前值
0000 0000 0001 0100 0000 0000 0000 0000

右移24位 等于0 --> n+=8=25
0000 0000 0000 0000 0000 0000 0000 0000

左移8位 source当前值
0001 0100 0000 0000 0000 0000 0000 0000

右移28位 不等于0 --> n和source都不变
0000 0000 0000 0000 0000 0000 0000 0001

右移30位 等于0 --> n+=2=27
0000 0000 0000 0000 0000 0000 0000 0000

左移2位 source当前值
0101 0000 0000 0000 0000 0000 0000 0000

source右移31位,等于0
0101 0000 0000 0000 0000 0000 0000 0000

n -= source >>> 31

最后得出n=27,1<<(32-n)=32,这个算法比较繁冗一点,理解起来也稍微困难些,这个算法的目的在于先求出当前数字的左边高位有多少个0,然后用32减去这个0的数量就是所需要的幂了。
这当中求0的数量的过程是个重点,也是通过位移来实现,先向右位移16次,如果等于0了,那说明前面16个高位都是0,n可以加16,如果不等于0,可以继续往下走,最后总归能让你等于0,这样计算累加下去就可以求出前面0的数量。
上面那段源码我没改方法名,可能有人能猜出代码的出处,那这段代码谁能猜到出自哪段源码呢?

源码出处

  • 第一段代码是HashMap里求threshold的过程,方法名就叫tableSizeFor
  • 第二段代码是出自Integer类的numberOfLeadingZeros方法,目的就是求出当前数字的左边高位有多少个0。这个方法调用的地方很多,ForkJoinPool,BigInteger,ConcurrentHashMap等等

单从求高一阶幂数这点来说,第一种算法更精妙一点,第二种略显笨拙,但是第二种算法也很好,用处也多。不管怎么说,位移始终是最贴近计算机的操作,是最快速的方法。

标签:0000,数字,16,int,source,给定,幂数,源码,0001
From: https://www.cnblogs.com/leecoder5/p/18420739

相关文章

  • 施耐德食品饮料精益数字化工厂MES项目解决方案:MES产品架构、MES产品解决方案
    施耐德食品饮料精益数字化工厂MES项目解决方案是一个综合性的解决方案,旨在通过MES(制造执行系统)实现食品饮料行业的智能制造和精益数字化工厂的构建。以下是对MES产品架构、MES产品解决方案以及PLC/DCS/SCADA/SAP的详细阐述: 一、MES产品架构MES产品架构通常根据企业的具体......
  • c#随机数 猜数字 彩票兑奖实操案例
    同学们今天给大家带来一个利用随机数,while循环语句,for语句,if判断语句制作的一个彩票兑奖的一个小案例,本文适合c#零基础的同学进行实操,所以用到的知识不是很多,主要学习for循环语句和if判断语句来进行程序的编写。写代码前我们需要明确我们要实现什么功能。1.用户需要输入0—......
  • 数字图像处理-实验4
    实验4:几何变换与变形实验4.1:图像透视变换将一幅输入图像变换为任意一个指定的四边形形状(给定四边形4个顶点)。提示:根据4个顶点的对应估计一个透视变换H,再用H对原图像进行形变(OpenCV相关函数:getPerspectiveTransform,warpPerspective等)设计一个交互程序,可以编辑四边形顶点,并且顶......
  • 一件部署安装百度开源数字人项目Hallo!图片视频!效果炸裂!含整合包!开源免费使用阿里蚂蚁
    一件部署安装百度开源数字人项目Hallo!图片视频!效果炸裂!含整合包!开源免费使用阿里蚂蚁集团推出的EchoMimic开源项目:为唱歌和对话提供支持的AI数字人技术(附代码)。近日,AI领域迎来了一个重磅消息——百度联合复旦大学、苏黎世联邦理工学院和南京大学共同推出一个开源项目,名为"Hallo"。......
  • 智慧农业:数字化管理与精准农业技术的未来
    在当今社会,科技的迅速发展正在深刻改变各行各业,农业亦不例外。随着全球人口不断攀升,传统农业面临着巨大的挑战:如何在有限的土地和资源上,实现可持续发展,保障粮食安全?答案在于智慧农业的崛起。#什么是智慧农业?智慧农业是运用先进的信息技术与数据分析方法,实现农业生产的智能化......
  • Unity自定义图片数字TextMeshPro
    本文转载自https://www.cnblogs.com/sailJs/p/181689221、首先要有一张包含了图片字的图集,每个图片字一个Spirte 2、然后右键-> 创建创建好的TMP_SpriteAsset 3、编辑SpriteCharacterTable调整顺序,将index和图片数字对上修改下Unicode值(默认都是0xFFFE),比如9的Un......
  • c++1095: 时间间隔(多实例测试) (字符串和字符以及数字的转换)
    问题描述:题目描述从键盘输入两个时间点(24小时制),输出两个时间点之间的时间间隔,时间间隔用“小时:分钟:秒”表示。要求程序定义如下两个函数,并在main()中调用这两个函数实现相应的功能/*三个形参分别为为用于表示一个时间点的时、分、秒,函数返回对应的秒。*/int HmsToS(int......
  • 重庆“1361数字城市”模式,入选国家数据局案例!
    近期,国家数据局发布《国家数字经济创新发展试验区建设案例集》。其中,数字重庆“打造三级数字化城市运行和治理中心 探索城市精准治理新路径”入选。关注“智慧城市指北”公众号,回复关键字“20240911”,获取获得“数字经济创新发展试验区建设案例集”(前20个案例)资料的方式,案例......
  • 数字增加
    importshutilimportos#假设文件在当前目录下source_directory='.'#源文件夹,可以根据需要修改file_prefix='0000'#文件名前缀file_suffix='.jpg'#文件名后缀#遍历1到15foriinrange(1,16):#生成源文件名和目标文件名src_file=os.p......
  • 健身房预约小程序定制搭建,数字化运营管理
    目前,健身已经成为了大众日常生活中不可或缺的一部分,不管是健身跑步、打羽毛球等,都受到了大众的欢迎!随着健身行业的快速发展,为了提高大众的健身体验,健身房预约系统得到了广泛发展。预约系统不仅解决了用户排队预约的问题,也能让健身房管理的更加高效!本文介绍健身房预约系统的功能特点......