java求余的技巧汇总

作者:一天不进步,就是退步 时间:2023-08-06 06:33:16 

背景

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

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解惑

来源:https://www.cnblogs.com/davidwang456/p/11577326.html

标签:java,求余,技巧
0
投稿

猜你喜欢

  • C语言实现稀疏矩阵

    2023-04-17 15:00:45
  • c# 代码调试技巧和如何远程调试

    2022-09-26 14:11:19
  • Java Map接口及其实现类原理解析

    2022-06-04 22:54:29
  • mybatis多个plugins的执行顺序解析

    2021-12-09 18:53:27
  • unity绘制一条流动的弧线(贝塞尔线)

    2022-09-03 18:15:00
  • spring boot动态切换数据源的实现

    2022-04-20 14:17:03
  • SpringBoot通过源码探究静态资源的映射规则实现

    2022-03-26 19:05:53
  • Java 如何使用Feign发送HTTP请求

    2023-05-10 15:04:08
  • Java多线程死锁示例

    2022-09-17 15:05:25
  • 浅谈Java中复制数组的方式

    2022-04-14 23:30:27
  • C# 位图BitArray的使用

    2022-09-13 23:54:46
  • Android 6.0指纹识别App开发案例

    2021-06-05 10:30:07
  • 浅谈利用Session防止表单重复提交

    2022-02-08 00:45:42
  • Java爬取网站源代码和链接代码实例

    2023-06-25 01:11:29
  • Java监听器ActionListener与MouseListener的执行顺序说明

    2022-02-04 20:08:23
  • Java 运算符详情

    2022-02-12 05:54:43
  • C#反射应用实例

    2023-11-03 14:47:46
  • Android组件ViewStub基本使用方法详解

    2022-01-15 07:30:54
  • Java数据结构之AC自动机算法的实现

    2023-08-31 07:23:57
  • JAVA 格式化日期、时间的方法

    2023-10-17 07:53:22
  • asp之家 软件编程 m.aspxhome.com