Java不用算数运算符来实现求和方法

 更新时间:2022年04月02日 15:06:28   作者:Scintillator. /  
我们都知道,Java的运算符除了具有优先级之外,还有一个结合性的特点。当一个表达式中出现多种运算符时,执行的先后顺序不仅要遵守运算符优先级别的规定,还要受运算符结合性的约束,以便确定是自左向右进行运算还是自右向左进行运算,但是如果不用运算符怎么求和呢

今天遇到了这样一个题

在这里插入图片描述

题目说了不能用算数运算符,那么我们就只能从 逻辑运算符 和 移位运算符 入手了。

我们知道 ^ (异或)操作是对两个数进行无进位求和,如果两个数相加本来就不产生进位,那么该和就是两数之和。 这就是解题的关键所在。一般来说,两数相加是会产生进位的,而要得到正确的和,应该是在 “无进位之和” 的基础上加上进位,那我们首先应该得到进位。我们知道,当两个数对应位置都为1的情况下,才会有进位的产生,即对应位置 A&B==1的条件下,就可以得到每一位的进位,但是进位是将这个1加到对应的更高一位,所以我们将得到的进位整体进行左移一位,再和之前得到的 “无进位之和” 相加,就可以得到两数之和。

我们发现这里就可以无限套娃了,要得到 “无进位之和” 和 “产生的进位” 之和,那么将这两个数再分别看做新的两个数,对其求和。也是重复之前的操作,直到两数不能产生进位,就可以直接通过 ^ 运算得到结果。

假设我们求 23 + 16 的值

在这里插入图片描述

在这里插入图片描述

根据上述思路,我们很容易就可以写出代码

public static int addAB(int A, int B) {
		// 当两数的产生的进位为 0,就退出循环,返回其无进位和,就是结果
        while ((A & B) != 0) {
            int A_B = A ^ B;// 无进位求和
            int AB = (A & B) << 1;// 得到进位
            // 接下来就是求 得到的进位 + 无进位之和,重复前面的操作,直到不产生进位
            A = A_B;
            B = AB;
        }
        // 最后返回新的无进位之和
        return (A ^ B);
    }

那么为了验证它的正确性,我们这里使用对数器,将该函数与 ’ + ’ 运算符比较。

public static void main(String[] args) {
    int count = 1_0000_0000;// 比较次数 100000000次
    Random random = new Random();// 生成随机数字
    boolean flag = true;// 相等则为 true

    for (int i = 0; i < count; i++) {
        int num1 = random.nextInt(Integer.MAX_VALUE/2);// 随机正数1
        int num1_2 = random.nextInt(Integer.MAX_VALUE/2);// 随机正数2
        // 随机正数1 + 随机正数2
        if ((num1+num1_2) != addAB(num1,num1_2)){
            // 有一次不相等的,则退出循环
            flag = false;
            break;
        }

        int num2 = -random.nextInt(Integer.MAX_VALUE/2);// 随机负数1
        int num2_2 = -random.nextInt(Integer.MAX_VALUE/2);// 随机负数2
        // 随机负数1  + 随机负数2
        if ((num2+num2_2) != addAB(num2,num2_2)){
            // 有一次不相等的,则退出循环
            flag = false;
            break;
        }

        int num3 = random.nextInt(Integer.MAX_VALUE);// 随机正数
        int num4 = -random.nextInt(Integer.MAX_VALUE);// 随机负数
        // 随机正数  + 随机负数
        if ((num3+num4) != addAB(num3,num4)){
            // 有一次不相等的,则退出循环
            flag = false;
            break;
        }
    }
    System.out.println(flag);
}

运行结果:

在这里插入图片描述

最后输出结果为 true ,说明我们计算随机产生的 正数+正数、负数+负数、正数+负数 分别100000000次,没有一次出错,说明该函数可靠。

到此这篇关于Java不用算数运算符来实现求和方法的文章就介绍到这了,更多相关Java 求和 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java之类加载机制案例讲解

    Java之类加载机制案例讲解

    这篇文章主要介绍了Java之类加载机制案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • SpringMVC配置404踩坑记录

    SpringMVC配置404踩坑记录

    本文主要介绍了SpringMVC配置404踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03
  • Spring如何动态自定义logback日志目录详解

    Spring如何动态自定义logback日志目录详解

    这篇文章主要给大家介绍了关于Spring如何动态自定义logback日志目录的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-10-10
  • Spring中利用配置文件和@value注入属性值代码详解

    Spring中利用配置文件和@value注入属性值代码详解

    这篇文章主要介绍了Spring中利用配置文件和@value注入属性值代码详解,代码中注释比较详细,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Springboot发送post请求的几种方式总结

    Springboot发送post请求的几种方式总结

    这篇文章主要为大家详细介绍了Springboot发送post请求的几种方式,文中的示例代码讲解详细,对我们学习或工作有一定的帮助,感兴趣的小伙伴可以了解一下
    2024-01-01
  • Java中Sentinel框架详解

    Java中Sentinel框架详解

    Sentinel是一个高可用、高扩展、高稳定性的开源流量控制和熔断降级框架,可以在分布式系统中实现实时的流量控制,防止系统因流量过大导致系统崩溃和服务降级,Sentinel面向所有的Java应用,本文就给大家详细介绍一下Java中Sentinel框架,需要的朋友可以参考下
    2023-06-06
  • 深入理解Spring Cloud Zuul过滤器

    深入理解Spring Cloud Zuul过滤器

    这篇文章主要给大家介绍了关于Spring Cloud Zuul过滤器的相关资料,通过阅读本文您将了解:Zuul过滤器类型与请求生命周期、如何编写Zuul过滤器、如何禁用Zuul过滤器和Spring Cloud为Zuul编写的过滤器及其功能,需要的朋友可以参考下。
    2017-02-02
  • Java实现word/pdf转html并在线预览

    Java实现word/pdf转html并在线预览

    这篇文章主要为大家详细介绍了如何利用Java语言实现word、pdf文件转html并在线预览的功能,文中的示例代码讲解详细,需要的可以参考一下
    2023-05-05
  • Spring Boot Actuator监控端点小结

    Spring Boot Actuator监控端点小结

    这篇文章主要介绍了Spring Boot Actuator监控端点小结,需要的朋友可以参考下
    2017-06-06
  • SpringBoot中启动时如何忽略某项检测

    SpringBoot中启动时如何忽略某项检测

    这篇文章主要介绍了SpringBoot中启动时如何忽略某项检测,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11

最新评论