年年有余之java求余的技巧集合
背景
传说里玉皇大帝派龙王马上降雨到共光一带,龙王接到玉皇大帝命令,立马从海上调水,跑去共光施云布雨,但粗心又着急的龙王不小心把海里的鲸鱼随着雨水一起降落在了共光,龙王怕玉皇大帝责怪,灵机一动便声称他是派鱼到共光,希望百姓可以年年有余,并请求玉皇大帝将这条鱼任命为鱼神,保佑人间太平可以年年有余。
年年有余
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求余的技巧集合的更多相关文章
- Java求余%引发的一连串故事
C1 RCE对%的处理 HotSpot VM的C1有个RCE(Range Check Elimination,范围检查消除)优化,所谓范围检查消除,就是为了正确的抛出数组越界异常,虚拟机需要在数组访问 ...
- java中的取整(/)和求余(%)
1.取整运算符取整从字面意思理解就是被除数到底包含几个除数,也就是能被整除多少次,那么它有哪些需要注意的地方呢?先看下面的两端代码: int a = 10; int b = 3; double c= ...
- java中求余%与取模floorMod的区别
初学java的时候接触的%这个符号 百分号? 求余? 取模? 我只知道不是百分号,好像是求余,听别人那叫求模运算符,跟求余一样,于是我便信了. 思考之后开始迷糊,然后经过多次考证得到以下结论. 首先, ...
- java 整除(/) 求余(%) 运算
1. java 整除(/) 求余(%) 运算 1.求余 System.out.println(11%2); //顾名思义就是11除2的余数-->1 System.out. ...
- c语言小技巧:C语言学习笔记之位运算求余
我们都知道,求一个数被另一个数整除的余数,可以用求余运算符”%“,但是,如果不 允许使用求余运算符,又该怎么办呢?下面介绍一种方法,是通过位运算来求余,但是注 意:该方法只对除数是2的N次方幂时才有效 ...
- ACM-ICPC 2018 焦作赛区网络预赛 G Give Candies(高精度求余)
https://nanti.jisuanke.com/t/31716 题意 n颗糖果n个人,按顺序给每个人任意数目(至少一个)糖果,问分配方案有多少. 分析 插板法或者暴力打表后发现答案就为2^(n- ...
- BigDecimal求余操作
BigDecimal求余操作如下: package com.qiu.lin.he; import java.math.BigDecimal; public class CeShi { public s ...
- Java 常用类库与技巧【笔记】
Java 常用类库与技巧[笔记] Java异常体系 Java异常相关知识 Java在其创立的时候就设置了比较有效的处理机制,其异常处理机制主要回答了三个问题:what,where,why what表示 ...
- C语言fmod()函数:对浮点数取模(求余)
头文件:#include <math.h> fmod() 用来对浮点数进行取模(求余),其原型为: double fmod (double x); 设返回值为 ret,那么 x = ...
随机推荐
- Android使用WebView开发常见的坑
原文链接:http://mp.weixin.qq.com/s?__biz=MzAwODE1NTI2MQ==&tempkey=uP3a%2BOgIN7vPbLfJp3BTCl2KabYi1%2F ...
- abp(net core)+easyui+efcore实现仓储管理系统——使用 WEBAPI实现CURD (十五)
core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+easyui+e ...
- Jmeter 02 Jmeter断言之响应断言
看完上一篇博客,相信大家应该可以使用Jmeter发送HTTP请求了.那么我们既然是要测试,就肯定需要判断结果了.Jmeter对于请求的响应数据提供了几种断言机制,这里大概说一下比较常用的几种断言. 响 ...
- [Python] Scrapy爬虫框架入门
说明: 本文主要学习Scrapy框架入门,介绍如何使用Scrapy框架爬取页面信息. 项目案例:爬取腾讯招聘页面 https://hr.tencent.com/position.php?&st ...
- Github资源下载
自己收集的一些日常使用软件.编程书籍以及自己动手实践的程序,欢迎下载. 收集维护不易,喜欢请Star或Fork支持呀,(^-^)V. 所有资源均自己制作或收集自网络,如有侵权请联系删除. 友情链接 G ...
- 基于ASP.Net Core开发的一套通用后台框架
基于ASP.Net Core开发一套通用后台框架 写在前面 这是本人在学习的过程中搭建学习的框架,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 知其然,知其所以然,并非重 ...
- 第6章 事务管理 6.1 spring事务
事务管理——原子性.一致性.隔离性.持久性 理解spring对事务管理的支持 Spring提供对编码式和声明式事务管理的支持.编码式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP,面 ...
- (一)LinkedList集合解析及手写集合
一.LinkedList集合特点 问题 结 论 LinkedList是否允许空 允许 LinkedList是否允许重复数据 允许 LinkedList是否有序 有序 LinkedList是否 ...
- 模板汇总——AC自动机
AC自动机 模板题 HDU-2222 Keywords Search #include<bits/stdc++.h> using namespace std; #define LL lon ...
- CF994B Knights of a Polygonal Table 第一道 贪心 set/multiset的用法
Knights of a Polygonal Table time limit per test 1 second memory limit per test 256 megabytes input ...