Java数值计算易出现的10种错误

简介: Java的数值计算容易出现很多错误,本文介绍Java数值计算易出现的10种错误。

错误1:整数除法得整数

这是老生常谈的话题了,也是很坑的一个点。

1 / 2 => 0

为啥?因为整数除法,得到整数,相当于应得的浮点数会被截断取整。

解决策略:先转型:

(double)1 / 2 => 0.5

错误2:运算后转型会溢出

之前在做洛谷OJ题解的时候多次提到这个问题:
比如两个int相乘再除以一个int,结果不会爆,但如果你使用int就会爆,甚至可能得到负数。
就算你用了long,也是先执行等号右边的计算,计算的类型还是int,只不过相当于先进行了运算后进行了转换。
我们要操作的话,宁可先转型后运算也不要弄颠倒了。

错误3:负数取模得负数

3 % 2 => 1
-1 % 2 => -1
-3 % 2 => -1
(-3) % 2 => -1

所以说,千万别以为负数会按照正数的规则去取模,当然,只不过互为相反数的两个数,取模结果也互为相反数。

补充,对负数取模会被认为是对其相反数取模。

取模的算法被模拟为Java代码大概是这样的(以a%b为例):

ans = a - a/b*b;

错误4:奇偶数判定不靠谱

这里有个讲究:奇偶数的判定,要用偶判断,不要用奇判断。

i % 2 == 1

上面的判断表达式就是奇判断,根据上面讲的取模的坑,我们就知道了,负数取模还是负数啊,怎么可能是正整数1呢?
所以,得到的偶数范围包含了正偶数、零和负整数。

其实,用下面的偶判断表达式更合理一些:

i % 2 == 0

(可以用位运算替换)

错误5:运算符不能算大数

大数要用 java.math.BigInteger 或者 java.math.BigDecimal ,这两个类都是非基本类型包装类的引用类型,也不是String这种特殊类型,所以用于基本运算的 + 、- 、* 、/ 就不好使了,应该使用对象的成员方法。

错误6:不要滥用++

++尽量不要乱用,尤其是在长表达式中。

错误7:不会取相反数

下面的代码是一个很好的处理方案:

a = -a;

错误8:不会构造BigInteger对象

BigInteger num1 = new BigInteger(1);

上面的代码并不对,BigInteger没有整数构造器参数,但可以使用String,所以可以这么写:

BigInteger num1 = new BigInteger("1");

或者:

int a = 1;
BigInteger num1 = new BigInteger(Integer.toString(a));

BigInteger类中有三个好使的静态属性:ZERO、ONE、TWO(TWO早期兼不兼容我不知道,但我知道洛谷OJ的Java8交上去TWO会CE)

注意静态导入(不好)或者自行使用,但却是减免了自己构造0、1、2的麻烦。

错误9:不会读大数

考虑到BigInteger要用String来构造,因此代码容易写成这样:

BigInteger num1 = new BigInteger(scanner.next());
BigDecimal num2 = new BigDecimal(scanner.nextDouble());

Scanner慢归慢,能力很强的,自然可以直接生成BigInteger和BigDecimal:

BigInteger num1 = scanner.nextBigInteger();
BigDecimal num2 = scanner.nextBigDecimal();

这不就省事了?

错误10:不熟悉各个基本类型的范围

别笑话,有时候真的让人迷惑。
再有一说是,Java缺几个东西:long double(真没有)、long long(实际上在Java里是long)、无符号数……

相关文章
|
Java
java: 错误: 无效的源发行版:15
java: 错误: 无效的源发行版:15
666 0
java: 错误: 无效的源发行版:15
|
Java 开发工具 C++
Java调用虹软SDK的错误
Java调用虹软SDK的错误
633 0
Java程序员最容易犯的十大SQL错误,你犯过几次?
前言 Java程序员编程时需要混合面向对象思维和一般命令式编程的方法,能否完美地将两者结合起来完全得依靠编程人员的水准: 技能:任何人都能容易学会命令式编程 模式:有些人用“模式-模式”,举个例子,模式可以应用到任何地方,而且都可以归为某一类模式 心境:首先,要写个好的面向对象程序是比命令式程序难得多,你得花费一些功夫 但当Java程序员写SQL语句时,一切都不一样了。SQL是说明性语言而非面向对象或是命令式编程语言。在SQL中要写个查询语句是很简单的。但在Java里类似的语句却不容易,因为程序员不仅要反复考虑编程范式,而且也要考虑算法的问题。 下面是Java程序员在写SQL时常犯的10个错误
|
Java
JAVA初学:错误: 找不到或无法加载主类 test
程序在运行的时候具体是如何确定.class文件位置的呢?
426 0
JAVA初学:错误: 找不到或无法加载主类 test
|
Java
命令行下运行JAVA出错:错误的签名:
命令行下运行JAVA出错:错误的签名:
81 0
|
Java Android开发
关于Java/Android开发中常见异常错误汇总___知识导图分享
注: 1.若博客图片不清晰,可以鼠标点击图片查看,或者下载到电脑中查看,也可以留言给我,发你高清原图。希望对热爱学习的朋友有帮助! 2.这是汇总的关于Java/Android开发中常见的异常、错误,绘制导图如下:
147 0
关于Java/Android开发中常见异常错误汇总___知识导图分享
|
Java 数据库
记录一次Java递归调用导致java.lang.StackOverflowError错误
通过递归调用每次查询500条数据的id,再通过id删除记录的方式,数据量一大,导致递归过深,栈帧数超出虚拟栈深度,虚拟机栈过多,报java.lang.StackOverflowError错误。
547 0
记录一次Java递归调用导致java.lang.StackOverflowError错误
|
前端开发 算法 JavaScript
Java初学者一定要注意的问题,这些错误你犯过哪些?永远不要停止学习。
Java初学者一定要注意的问题,这些错误你犯过哪些?永远不要停止学习。
Java初学者一定要注意的问题,这些错误你犯过哪些?永远不要停止学习。
【问题一】notepad++编辑器写Java代码,无法编译出现错误:编码GBK的不可映射字符
今天在学习“流程控制”一节,用notepad++写代码时,一直报错,无法编译。看了好多遍代码,代码完全正确,非常纳闷。
【问题一】notepad++编辑器写Java代码,无法编译出现错误:编码GBK的不可映射字符