java求余的技巧汇总

背景

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

年年有余

java 求余操作初阶

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

例1:

int a = 5%3; // 2
int b = 5/3; // 1
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); // 2
    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); // 1
    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解惑

总结

以上就是我在处理客户端真实IP的方法,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • 浅析java中的取整(/)和求余(%)

    1.取整运算符 取整从字面意思理解就是被除数到底包含几个除数,也就是能被整除多少次,那么它有哪些需要注意的地方呢?先看下面的两端代码: int a = 10; int b = 3; double c= a / b; System.out.println(c); 第一段代码的运行结果是3.0, 其中double c = a / b;//c = (10/3) = (double)3 = 3.0,这里面涉及到一个低精度到高精度的隐式装换. int a = 10; int b = 3; double c

  • java求余的技巧汇总

    背景 传说里玉皇大帝派龙王马上降雨到共光一带,龙王接到玉皇大帝命令,立马从海上调水,跑去共光施云布雨,但粗心又着急的龙王不小心把海里的鲸鱼随着雨水一起降落在了共光,龙王怕玉皇大帝责怪,灵机一动便声称他是派鱼到共光,希望百姓可以年年有余,并请求玉皇大帝将这条鱼任命为鱼神,保佑人间太平可以年年有余. 年年有余 java 求余操作初阶 java中也有余的规范[jls-15.17.3],废话不说,直接上代码,从中我们可以学到很多技巧: 例1: int a = 5%3; // 2 int b = 5/3;

  • Java求余%操作引发的一连串故事

    操作符%通常用在正整数上,但同样可以用在负整数和浮点数上. 注意:只有当被除数是负数时, 余数才是负的. C1 RCE对%的处理 HotSpot VM的C1有个RCE(Range Check Elimination,范围检查消除)优化,所谓范围检查消除,就是为了正确的抛出数组越界异常,虚拟机需要在数组访问的一些地方插入隐式的检查,但是这些检查会降低性能,比如在循环中每次循环都得检查一次,所以HotSpot VM会想办法在可能的地方消除这些检查.我在看C1 RCE的时候发现目前它对求余符号的支持较

  • java求最大公约数与最小公倍数的方法示例

    本文实例讲述了java求最大公约数与最小公倍数的方法.分享给大家供大家参考,具体如下: Gongyueshu.java文件: package math; public class Gongyueshu { public static void main(String[] args) { //从控制台输入两个数据 int m = Integer.parseInt(args[0]); int n = Integer.parseInt(args[1]); int y = 1 ; int b = 1;

  • Java求10到100000之间的水仙花数算法示例

    本文实例讲述了Java求10到100000之间的水仙花数算法.分享给大家供大家参考,具体如下: 水仙花数: 概念:水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身.(例如:1^3 + 5^3+ 3^3 = 153) 算法思路分析:这个算法我们分两个步骤来进行:第一:我们做一个求一个数的位数的函数:第二:我们通过调用此函数来进行10到100000之间素数的计算! 下面给出具体的代码(仅供参考): package javastudy; public class

  • Java求质数的几种常用算法分析

    本文实例讲述了Java求质数的几种常用算法.分享给大家供大家参考,具体如下: 1.根据质数的定义求 质数定义:只能被1或者自身整除的自然数(不包括1),称为质数. 利用它的定义可以循环判断该数除以比它小的每个自然数(大于1),如果有能被它整除的,则它就不是质数. 对应代码是: void printPrime(int n){//判断n是否是质数 boolean isPrime=true;//是否是质数的标志 for(int i=n-1;i>1;i-){//n除以每个比n小比1大的自然数 if(n%

  • 一文详解Java中的Stream的汇总和分组操作

    目录 前言 一.查找流中的最大值和最小值 二.汇总 三.连接字符串 四.分组 1.分组 2.多级分组 3.按子组数据进行划分 后记 前言 在前面的文章中其实大家也已经看到我使用过collect(Collectors.toList()) 将数据最后汇总成一个 List 集合. 但其实还可以转换成Integer.Map.Set 集合等. 一.查找流中的最大值和最小值 static List<Student> students = new ArrayList<>(); ​ static

  • Lua中关于求模与求余的区别介绍

    我觉得很多人搞不清楚这两个概念的区别,刚好在翻译lua手册时遇到%与math.fmod这两个操作,顺便做一下说明吧. 求模与求余的区别. 假设对a与b两个整数做求模或求余操作.那么第一步是先求整数商c,即a / b的值,第二步是计算模或余数:a - c * b.求模与求余的区别在于怎么处理a / b的值. 求模运算时,a / b的结果向无穷小方向舍入,求余运算时a / b的结果向0方向舍入. 因此,求模时结果的符号与b一致,求余时结果的符号与a一致. 在Lua中4%(-3)等于-2,由此可以看出

  • java求100之内的素数(质数)简单示例

    质数又称素数.一个大于1的自然数,如果除了1和它自身外,不能被其他自然数整除的数:否则称为合数.根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积:而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的.下面是一个java求100之内的素数简单示例 复制代码 代码如下: public class test { public static void main(String[] args) {  int i,n,k=0;     for (n = 3; n

  • java求两个数中的大数(实例讲解)

    java中的max函数在Math中 应用如下: int a=34: int b=45: int ans=Math.max(34,45); 那么ans的值就是45. 以上这篇java求两个数中的大数(实例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

随机推荐