当前位置: 主页 > JAVA语言

java math.random()返回值范围-(知识点)引号内存牺牲精确性的常见问题错误形式

发布时间:2023-06-10 10:10   浏览次数:次   作者:佚名

常见问题

错误形式

正确表达说明

结果不精确

System.out.println(0.1 + 0.2 - 0.3 == 0);

输出不是true。

double类型数据不一定能够精确表示,尽量使用int或long型数据做数值运算。一定要用double类型时务必要注意可能存在的误差。

需要判断一个数(例如二次方程判断式)是否为0,可以判断其绝对值是否小于一个充分小的数:

double a = 0.1 + 0.2 – 0.3;

double zero = 1e-6;

Boolean isZero = Math.abs(a) < zero;

漏掉后缀

float f = 3.14;

有编译错误。

浮点数常量默认为double类型。不得已需要将浮点数其表示为float型时应加后缀F:

float f = 3.14F;

float类型数据不够精确,使用还麻烦,不必为了节约四个字节内存牺牲精确性,强烈不推荐使用。

字符和字符串混淆

char c = 'ab';

编译错误。

字符型变量只能存储单个字符,字符型常量写在一对单引号''内。需要存储多个字符时需要使用字符串类型String变量,字符串常量写在一对双引号""内:

String s = "ab";

忘记使用转义字符

char c = ''';

java math.random()返回值范围_js math.random 范围_java中math.random

编译错误。

特殊字符(单引号',双引号",反斜线\,回车java math.random()返回值范围,制表位等)必须使用转义字符方式书写:

char c = '\'';

没有做字符串连接

System.out.println('A' + 'B');

输出的结果并不是AB。

System.out.println('A' + 1);

输出的结果不是B也不是A1。

用加号+做字符串连接的条件是左右两侧至少有一个是字符串,否则做数值加法。

解决办法是将其中一个变为字符串,或先与空字符串""连接生成字符串。以下语句都输出AB:

System.out.println("A" + 'B');

System.out.println("" + 'A' + 'B');//万能办法

变量反复定义

int a = 1;

double a = 2;

编译错误。

变量必须先声明java math.random()返回值范围,再赋值,后使用,并且在其作用域内只能被声明一次,声明后类型固定不变。

变量装不下数据

int a = 3.14;

编译错误。

变量只能装下与其表示范围一致或更小的数据。double类型的表示范围远远大于int的表示范围,此处需要用强制类型转换,小数部分被截断。

int a = (int)(3.14);

定义变量时务必考虑要存储数据的范围,例如手机号不能用int型而要用long型存储;身份证号不能用long型而要用String型存储。

int a = Math.sqrt(4);

java中math.random_js math.random 范围_java math.random()返回值范围

4的平方根是2,但编译错误。

Math类中的方法返回值都是double类型数据。错误原因同上。

boolean a = 1;

int b = (int)("123");

编译错误。

Java语言中boolean和String类型数据都不是数值,无法和数值进行双向自动或强制类型转换。

交换变量失败

a = b;

b = a;

交换变量一般需要通过临时变量,否则a中数值会被覆盖而丢失:

temp = a;

a = b;

b = temp;

结果不是字符而是数值

System.out.println('A' + 1);

不输出B。

由于自动类型转换,char型数据做数值运算会被提升为int型以上,想要将结果作为一个Unicode转换回字符,需要强制类型转换:

System.out.println((char)('A' + 1));

乘号被省略

int a = 1, b = 2, c = ab, d = 3(a + b);

编译错误。

乘号不可以被省略,此处ab是与a和b都不同的变量,3(也是不能被理解的表达式。

int a = 1, b = 2, c = a * b, d = 3 * (a + b);

结果因整数除法错误

java中math.random_js math.random 范围_java math.random()返回值范围

double r = 1, h = 1;

double v = 1 / 3 * Math.PI * r * r * h;

计算圆锥体积,但v的结果为0。

int n = 5;

double a = 6;

double b = Math.pow(a, 1 / n);

求a的n次方根结果总是1。

当除号/两侧都是整数时,执行的是整数除法,结果是数学结果的整数部分,小数部分被丢弃。想要精确结果,至少将被除数或除数之一转换为double类型:

1.0 / 3 * Math.PI * r * r * h

1 / 3.0 * Math.PI * r * r * h

1.0 / 3.0 * Math.PI * r * r * h

(double)(1) / 3 * Math.PI * r * r * h

……

Math.pow(a, 1 / (double)(n))

乘方书写错误

a^n

运算符^在Java语言中并不表示乘方,计算a的n次方需要使用方法Math.pow(a,n)。

结果因优先级错误

要生成0到n的随机整数,但(int)Math.random() * n得到的总是0。

单目运算符的优先级比算术运算符高,Math.random()生成的是介于0和1之间的纯小数,经过强制类型转换为int后结果总是0。

不要背优先级,将需要先计算的部分放入括号中保证优先级:(int)(Math.random() * n)。

==和=混淆

System.out.println(1 = 2);

编译错误。

java math.random()返回值范围_js math.random 范围_java中math.random

=为赋值运算符,左侧必须是变量(左值),表达式结果是左侧变量的值;==为比较运算符,结果为boolean值,true或false。

双边不等式

int a = 1, b = 2, c = 3;

System.out.println(a > b > c);

编译错误。

比较运算符的结果都是boolean值,true或false,不能再和数值作比较运算,双边不等式务必使用逻辑运算符连接:(a > b) && (b > c)。

闰年的判断

忘记是否整除400和100的条件,结果3000年被误判为闰年。

判断一个年份n是否为闰年的正确表达式:

(n % 400 == 0) || ((n % 100 != 0) && (n % 4 == 0))

滥用++和--

i+++i+i+++i

++和—一定单独使用,不要和其他运算符混合在一起,否则代码可读性太差。

输入数据错误

Scanner类没导入就定义对象,编译错误。

Scanner input = new Scanner(System.in);

Scanner类在使用前必须导入,import语句写在package语句后,类定义之前。

import java.util.Scanner;

int i = input.nextDouble();

编译错误。

等号右侧读取double类型数据,左侧却是int型变量,需改为input.nextInt(),或进行强制类型转换。

int i = input.nextInt();

用户输入3.14,运行时异常。

nextInt()方法读取int型数据,用户输入double类型数据,类型不匹配,用户只能输入int型数据,或将语句改为以下以读取double型数据:

js math.random 范围_java中math.random_java math.random()返回值范围

double d = intput.nextDouble();

char c = input.nextChar();

编译错误。

Scanner类型对象没有nextChar()方法,读取单个字符需要先读整个字符串,再取首个字符:

char c = input.nextLine().charAt(0);

int age = input.nextInt();

String name = input.nextLine();

double height = input.nextDouble();

用户输入:20 回车 Tom 回车 1.8 回车

程序运行时异常。事实上,用户没有机会输入1.8即已产生异常。

nextInt()、nextDouble()和next()的特点:从非空字符(空格、回车、制表位等)开始读取,直到空字符结束,空字符留在输入流中。

nextLine()的特点:从任意字符开始读取,直到回车结束,回车被从输入流中取出并丢弃。

nextInt()读取20后,回车还在输入流中,残留的回车被nextLine()读取到,当做字符串结束,所以name是个空字符串"",字符串Tom被nextDouble()读取引发异常。

临时解决方法1:将nextLine()替换为next()忽略残留回车

String name = scan.next();

next()会跳过20后的回车,从非空字符开始读取,读到Tom后的回车结束,nextDouble()也会跳过Tom后的回车,读到1.8。

临时解决方案2:调换nextInt()和nextLine()的顺序,先读字符串name,再读数值age,避免读数值age后的回车残留干扰。

临时解决方案3:在读取数值age之后,读取字符串name之前加语句input.nextLine();读取并丢弃读数值age后残留的回车。

更好的解决方案将在学习包装类后介绍。

中文乱码

程序正确,但输出中文乱码

Java没有正确解码操作系统读取并编码的中文字符。

如果是用Netbeans编程,右键单击项目-属性-编码,改为GB18030。

java math.random()返回值范围_java中math.random_js math.random 范围

java中math.random_js math.random 范围_java math.random()返回值范围