背景

  传说里玉皇大帝派龙王马上降雨到共光一带,龙王接到玉皇大帝命令,立马从海上调水,跑去共光施云布雨,但粗心又着急的龙王不小心把海里的鲸鱼随着雨水一起降落在了共光,龙王怕玉皇大帝责怪,灵机一动便声称他是派鱼到共光,希望百姓可以年年有余,并请求玉皇大帝将这条鱼任命为鱼神,保佑人间太平可以年年有余。

                                      年年有余

java 求余操作初阶

java中也有余的规范【jls-15.17.3】,废话不说,直接上代码,从中我们可以学到很多技巧:

例1:

        int a = 5%3; //
int b = 5/3; //
System.out.println("5%3 produces " + a +" (note that 5/3 produces " + b + ")");

相信大多数人都知道结果了:

          5%3 produces 2 (note that 5/3 produces 1)

java 求余操作中阶

我们知道,正数不仅仅有正整数还有负整数,那么负数的情况下,会出现什么变化呢?

例2:

        int c = 5%(-3); //
int d = 5/(-3); // -1
System.out.println("5%(-3) produces " + c +" (note that 5/(-3) produces " + d + ")");
int e = (-5)%3; // -2
int f = (-5)/3; // -1
System.out.println("(-5)%3 produces " + e +" (note that (-5)/3 produces " + f + ")");
int g = (-5)%(-3); // -2
int h = (-5)/(-3); //
System.out.println("(-5)%(-3) produces " + g +" (note that (-5)/(-3) produces " + h + ")");

能完全正确得到结果的就很少了吧?

          5%(-3) produces 2 (note that 5/(-3) produces -1)
          (-5)%3 produces -2 (note that (-5)/3 produces -1)
          (-5)%(-3) produces -2 (note that (-5)/(-3) produces 1)

为什么求余的结果是这样的呢?jls-15.17.3规范告诉我们:

The binary % operator is said to yield the remainder of its operands from an implied division; the left-hand operand is the dividend and the right-hand operand is the divisor.
It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive. Moreover, the magnitude of the result is always less than the magnitude of the divisor.

注意:求余的正负数给dividend(左边操作数)的符号位一致!

java 求余操作高阶

java求余操作不但支持整数还支持浮点数

class Test2 {
public static void main(String[] args) {
double a = 5.0%3.0; // 2.0
System.out.println("5.0%3.0 produces " + a);
double b = 5.0%(-3.0); // 2.0
System.out.println("5.0%(-3.0) produces " + b);
double c = (-5.0)%3.0; // -2.0
System.out.println("(-5.0)%3.0 produces " + c);
double d = (-5.0)%(-3.0); // -2.0
System.out.println("(-5.0)%(-3.0) produces " + d);
}
}

相信很多人可以根据整型的规则,得出正确的结果

5.0%3.0 produces 2.0
5.0%(-3.0) produces 2.0
(-5.0)%3.0 produces -2.0
(-5.0)%(-3.0) produces -2.0

补充一下,浮点型的求余有一些特殊的规则:

The result of a floating-point remainder operation as computed by the % operator is not the same as that produced by the remainder operation defined by IEEE 754. The IEEE 754 remainder operation computes the remainder from a rounding division, not a truncating division, and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java programming language defines % on floating-point operations to behave in a manner analogous to that of the integer remainder operator; this may be compared with the C library function fmod. The IEEE 754 remainder operation may be computed by the library routine Math.IEEEremainder.

The result of a floating-point remainder operation is determined by the rules of IEEE 754 arithmetic:

If either operand is NaN, the result is NaN.
If the result is not NaN, the sign of the result equals the sign of the dividend.
If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is finite, the result equals the dividend.
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from the division of a dividend n by a divisor d is defined by the mathematical relation r = n - (d ⋅ q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.
Evaluation of a floating-point remainder operator % never throws a run-time exception, even if the right-hand operand is zero. Overflow, underflow, or loss of precision cannot occur.

java 求余操作骨灰级

学到这里,或许有人沾沾自喜,我都掌握了求余的所有规则,看来需要给你泼泼冷水:

    public static void main(String[] args) {
final int MODULUS = 3;
int[] histogram = new int[MODULUS];
// Iterate over all ints (Idiom from Puzzle 26)
int i = Integer.MIN_VALUE;
do {
histogram[Math.abs(i) % MODULUS]++;
} while (i++ != Integer.MAX_VALUE);
for (int j = 0; j < MODULUS; j++)
System.out.println(histogram[j] + " ");
}

这个程序会打印什么?有人经过繁琐复杂的算出一个结果:

1431655765 1431655766 1431655765

但其实,上述程序运行报错:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
at com.java.puzzlers.ModTest.main(ModTest.java:11)

为什么数组会出现索引 -2?奇怪吧?要回答这个问题,我们必须要去看看Math.abs 的文档

 /**
* Returns the absolute value of an {@code int} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
*
* <p>Note that if the argument is equal to the value of
* {@link Integer#MIN_VALUE}, the most negative representable
* {@code int} value, the result is that same value, which is
* negative.
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static int abs(int a) {
return (a < 0) ? -a : a;
}
特意说明,如果是Integer#MIN_VALUE,返回负数

java里有很多小技巧,需要我们勤翻api和jsl,多学习多练习。

参考资料:

【1】https://baike.baidu.com/item/%E5%B9%B4%E5%B9%B4%E6%9C%89%E4%BD%99/7625174?fr=aladdin

【2】https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.17.3

【3】java解惑

年年有余之java求余的技巧集合的更多相关文章

  1. Java求余%引发的一连串故事

    C1 RCE对%的处理 HotSpot VM的C1有个RCE(Range Check Elimination,范围检查消除)优化,所谓范围检查消除,就是为了正确的抛出数组越界异常,虚拟机需要在数组访问 ...

  2. java中的取整(/)和求余(%)

    1.取整运算符取整从字面意思理解就是被除数到底包含几个除数,也就是能被整除多少次,那么它有哪些需要注意的地方呢?先看下面的两端代码: int a = 10; int b = 3; double c= ...

  3. java中求余%与取模floorMod的区别

    初学java的时候接触的%这个符号 百分号? 求余? 取模? 我只知道不是百分号,好像是求余,听别人那叫求模运算符,跟求余一样,于是我便信了. 思考之后开始迷糊,然后经过多次考证得到以下结论. 首先, ...

  4. java 整除(/) 求余(%) 运算

    1. java 整除(/)  求余(%)  运算 1.求余    System.out.println(11%2);     //顾名思义就是11除2的余数-->1    System.out. ...

  5. c语言小技巧:C语言学习笔记之位运算求余

    我们都知道,求一个数被另一个数整除的余数,可以用求余运算符”%“,但是,如果不 允许使用求余运算符,又该怎么办呢?下面介绍一种方法,是通过位运算来求余,但是注 意:该方法只对除数是2的N次方幂时才有效 ...

  6. ACM-ICPC 2018 焦作赛区网络预赛 G Give Candies(高精度求余)

    https://nanti.jisuanke.com/t/31716 题意 n颗糖果n个人,按顺序给每个人任意数目(至少一个)糖果,问分配方案有多少. 分析 插板法或者暴力打表后发现答案就为2^(n- ...

  7. BigDecimal求余操作

    BigDecimal求余操作如下: package com.qiu.lin.he; import java.math.BigDecimal; public class CeShi { public s ...

  8. Java 常用类库与技巧【笔记】

    Java 常用类库与技巧[笔记] Java异常体系 Java异常相关知识 Java在其创立的时候就设置了比较有效的处理机制,其异常处理机制主要回答了三个问题:what,where,why what表示 ...

  9. C语言fmod()函数:对浮点数取模(求余)

    头文件:#include <math.h> fmod() 用来对浮点数进行取模(求余),其原型为:    double fmod (double x); 设返回值为 ret,那么 x = ...

随机推荐

  1. python之爬虫-必应壁纸

    python之爬虫-必应壁纸 import re import requests """ @author RansySun @create 2019-07-19-20:2 ...

  2. shiro登录名的获取

    登录名的获取:通过的SecurityUtils的shiro import org.apache.shiro.SecurityUtils; //登录用户名 String loginAccount = S ...

  3. springboot的mybatis的xml相关的配置

    POM文件的配置: mybatis.type-aliases-package=com.handsight.platform.fras mybatis.mapper-locations=classpat ...

  4. Appium+python自动化(三十五)- 命令启动appium之 appium服务命令行参数(超详解)

    简介 前边介绍的都是通过按钮点击启动按钮来启动appium服务,有的小伙伴或者童鞋们乍一听可能不信,或者会问如何通过命令行启动appium服务呢?且听宏哥一一道来. 一睹为快 其实相当的简单,不看不知 ...

  5. MQTT服务器(Win)

    系统环境准备 Java JDK >=1.6,系统环境变量配置JAVA HOME 链接:https://pan.baidu.com/s/1OO-KCdsCrdfjMtf6BVNl6Q 提取码:dy ...

  6. CNN中1x1 卷积的处理过程及作用

    参看:https://blog.csdn.net/ybdesire/article/details/80314925

  7. Egret白鹭开发微信小游戏(使用皮肤搭建UI,代码调用组件功能)

    (1)新建皮肤,并命名如下 (2)根据实际情况自定义皮肤,例如: (3)修改名字为如下: (4)运行游戏会自动生成以下代码: (5)在default.thm.json中添加如下代码:(具体路径名字根据 ...

  8. unity,C#,游戏面试笔试真题

    最开始的两家公司笔试面试题目 一家公司是学校聘请研究教育方面VR课件的公司,面试没几天,就收到了面试通过的消息,后面因为通过了另一家游戏公司而拒绝了. 另一家公司是一家游戏外企,在春熙路,当时笔试还可 ...

  9. C#使用iTextSharp给PDF文件加水印

    给PDF添加水印,可以用iTextSharp. 步骤1:下载iTextSharp 步骤2:在项目中添加引用itextsharp.dll 步骤3:在程序中使用iTextSharp.text.pdf us ...

  10. Linux中JDK安装配置

    安装jdk 1)下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html 我选择jdk1.8版本 2)上传至服务 ...