我是靠谱客的博主 纯真白羊,最近开发中收集的这篇文章主要介绍java核心技术卷1---运算符,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Java 中,使用算术运算符+、-、*/ 表示加、减、乘、除运算。当参与 / 运算的两个操作数都是整数时,表示整数除法;否则,表示浮点除法。整数的求余操作(有时称为取模)用 % 表示。例如,15/2 等于 715%2 等于 115.0/2 等于 7.5

需要注意,整数被 0 除将会产生一个异常,而浮点数被 0 除将会得到无穷大或 NaN 结果。可以在赋值语句中采用一种简化的格式书写二元算术运算符。
例如,

等价于
(通常,将运算符放在赋值号的左侧,如
*= %=。)

注释:可移植性是 Java 语言的设计目标之一。无论在哪个虚拟机上运行,同一运算应该得到同样的结果。对于浮点数的算术运算,实现这样的可移植性是相当困难的。double类型使用 64 位存储一个 double 数值,而有些处理器使用 80 位浮点寄存器。这些寄存器增加了中间过程的计算精度。例如,下列运算:

很多 Intel 处理器计算 x * y,并且将结果存储在 80 位的寄存器中,再除以 z 并将结果截断为 64 位。这样可以得到一个更加精确的计算结果,并且还能够避免产生指数溢出。但是,这个结果可能与始终在 64 位机器上计算的结果不一样。因此,Java 虚拟机的最初规范规定所有的中间计算都必须进行截断。这种行为遭到了数值计算团体的反对。截断计算不仅可能导致溢出,而且由于截断操作需要消耗时间,所以在计算速度上要比精确计算慢。为此,Java 程序设计语言承认了最优性能与理想结果之间存在的冲突,并给予了改进。在默认情况下,虚拟机设计者允许将中间计算结果采用扩展的精度。但是,

403 Java 的基本程序设计结构
对于使用 strictfp 关键字标记的方法必须使用严格的浮点计算来产生理想的结果。例如,

可以把 main 方法标记为

于是,在 main 方法中的所有指令都将使用严格的浮点计算。如果将一个类标记为strictfp,这个类中的所有方法都要使用严格的浮点计算。

实际的计算方式将取决于 Intel 处理器。在默认情况下,中间结果允许使用扩展的指数,但不允许使用扩展的尾数(Intel 芯片在截断尾数时并不损失性能)。因此,这两种方式的区别仅仅在于采用默认的方式不会产生溢出,而采用严格的计算有可能产生溢出。

如果没有仔细阅读这个注释,也没有什么关系。对大多数程序来说,浮点溢出不属于大问题。在本书中,将不使用 strictfp 关键字。

3.5.1 自增运算符与自减运算符

当然,程序员都知道加 1、减 1 是数值变量最常见的操作。在 Java 中,借鉴了 C C++的实现方式,也使用了自增、自减运算符:n++ 将变量 n 的当前值加 1 ;n–– n 的值减 1。例如:

n 的值将变为 13。因为这些运算符改变了变量的值,所以它的操作数不能是数值。例如,4++ 就是一条非法的语句。

实际上,这两个运算符有两种形式。上面介绍的是运算符放在操作数后面的“后缀”形式,还有一种“前缀”形式,++n。两种方式都是对变量值加 1。但在表达式中,这两种形式就有区别了。前缀方式先进行加 1 运算;后缀方式则使用变量原来的值。

我们建议不要在其他表达式的内部使用 ++,这样编写的代码很容易令人困惑,并会产生烦人的 bug

(当然,++ 运算符作为 C++ 语言名称的一部分,也引发了有关程序设计语言的第一个笑话。C++ 的反对者认为这种语言的名称也存在着 bug,他们说:“因为只有对它改进之后,我们才有可能使用它,所以它的名字应该命名为 ++C。”)

3.5.2 关系运算符与 boolean 运算符

Java 包含各种关系运算符。其中,使用两个等号 = = 检测是否相等。例如,3 = = 7 的值为 false

使用 != 检测是否不相等。例如,3 != 7 的值为 true
另外,经常使用的运算符还有
<(小于)、>(大于)、<=(小于等于)和 >=(大于等于)。

3.5 运算符 41

Java 沿用了 C++ 的习惯,用 && 表示逻辑“与”、用 || 表示逻辑“或”。从 != 运算符很容易看出,! 表示逻辑“非”。&& || 是按照“短路”方式求值的。如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。如果用 && 对两个表达式进行计算:

并且第一个表达式值为 false,结果不可能为真。因此,第二个表达式的值就没有必要计算了。这种方式可以避免一些错误的发生。例如,表达式:

x 0 时,不会计算第二部分。因此,若 x 01/x 不被计算,也不会出现除以 0 的错误。与之类似,对于 expression1 || expression2,当第一个表达式为 true 时,结果自动为 true

不必再计算第二部分。
最后,
Java 支持三元操作符 ?:。在很多时候,这个操作符非常有用。表达式

当条件 condition 为真时计算第 1 个表达式,否则计算第 2 个表达式。例如:

返回 x y 中较小的那个值。3.5.3 位运算符

在处理整型数值时,可以直接对组成整型数值的各个位进行操作。这意味着可以使用屏蔽技术获得整数中的各个位。位运算符包括:

&(" ")、|(" ")、^(" 异或 ")、~(" ")

这些运算符在位模式下工作。例如,如果 n 是一个整型变量,并且用二进制表示的 n 从右数第 4 位为 1,那么

返回 1 ;否则返回 0。通过运用 2 的幂次方的 & 运算可以将其他位屏蔽掉,而只保留其中的某一位。

注释:& | 运算符应用于布尔值,得到的结果也是布尔值。这两个运算符与 && ||的运算非常类似,只是不按“短路”方式计算。即在得到计算结果之前,一定要计算两个操作数的值。

另外,“ >>”和“ <<”运算符将二进制位进行右移或左移操作。当需要建立位模式屏蔽某些位时,使用这两个运算符十分方便:

最后,>>> 运算符将用 0 填充高位;>> 运算符用符号位填充高位。没有 <<< 运算符。

警告:对移位运算符右侧的参数需要进行模 32 的运算(除非左边的操作数是 long 类型,在这种情况下需对右侧操作数模 64)。例如,1 << 35 1 << 3 8 是相同的。

423 Java 的基本程序设计结构

C++ 注释:C C++ 中无法确定 >> 操作执行的是算术移位(扩展符号位),还是逻辑移位(高位填 0)。在执行中将会选择效率较高的一种。这就是说,在 C/C++ 中,>> 运算符实际上只是为非负数定义的。Java 消除了这种含糊性。

3.5.4 数学函数与常量

Math 类中,包含了各种各样的数学函数。在编写不同类别的程序时,可能需要的函数也不同。

要想计算一个数值的平方根,可以使用 sqrt 方法:

注释:println 方法和 sqrt 方法存在微小的差异。println 方法操作一个定义在 System 类中的 System.out 对象。但是,Math 类中的 sqrt 方法处理的不是对象,这样的方法被称为静态方法。有关静态方法的详细内容请参看第 4 章。

Java 中,没有幂运算,因此需要借助于 Math 类的 pow 方法。语句:

y 的值设置为 x a 次幂(xa)。pow 方法有两个 double 类型的参数,其返回结果也为double 类型。

Math 类提供了一些常用的三角函数:

还有指数函数以及它的反函数自然对数以及以 10 为底的对数:最后,Java 还提供了两个用于表示 p e 常量的近似值:

提示:不必在数学方法名和常量名前添加前缀“ Math.”,只要在源文件的顶部加上下面这行代码就可以了。

例如:
在第
4 章中将讨论静态导入。

注释:Math 类中,为了达到最快的性能,所有的方法都使用计算机浮点单元中的例程。如果得到一个完全可预测的结果比运行速度更重要的话,那么就应该使用 StrictMath类。它使用“自由发布的 Math 库”(fdlibm)实现算法,以确保在所有平台上得到相同的结果。有关这些算法的源代码请参看 www.netlib.org/fdlibm(当 fdlibm 为一个函数提供了多个定义时,StrictMath 类就会遵循 IEEE 754 版本,它的名字将以“e”开头)。

3.5.5 数值类型之间的转换在程序运行时,经常需要将一种数值类型转换为另一种数值类型。图 3-1 给出了数值类

型之间的合法转换。

3.5 运算符 43

3-1 数值类型之间的合法转换

在图 3-1 中有 6 个实心箭头,表示无信息丢失的转换;有 3 个虚箭头,表示可能有精度损失的转换。例如,123 456 789 是一个大整数,它所包含的位数比 float 类型所能够表达的位数多。当将这个整型数值转换为 float 类型时,将会得到同样大小的结果,但却失去了一定的精度。

当使用上面两个数值进行二元操作时(例如 n + fn 是整数,f 是浮点数),先要将两个操作数转换为同一种类型,然后再进行计算。

如果两个操作数中有一个是 double 类型,另一个操作数就会转换为 double 类型。否则,如果其中一个操作数是 float 类型,另一个操作数将会转换为 float 类型。
否则,如果其中一个操作数是 long 类型,另一个操作数将会转换为 long 类型。
否则,两个操作数都将被转换为 int 类型。

3.5.6 强制类型转换

在上一小节中看到,在必要的时候,int 类型的值将会自动地转换为 double 类型。但另一方面,有时也需要将 double 转换成 int。在 Java 中,允许进行这种数值之间的类型转换。

443 Java 的基本程序设计结构

当然,有可能会丢失一些信息。在这种情况下,需要通过强制类型转换(cast)实现这个操作。强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名。例如:

这样,变量 nx 的值为 9。强制类型转换通过截断小数部分将浮点值转换为整型。如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下,希望使用这种

操作方式),那就需要使用 Math.round 方法:

现在,变量 nx 的值为 10。当调用 round 的时候,仍然需要使用强制类型转换(int)。其原因是 round 方法返回的结果为 long 类型,由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能够将 long 类型转换成 int 类型。

警告:如果试图将一个数值从一种类型强制转换为另一种类型,而又超出了目标类型的表示范围,结果就会截断成一个完全不同的值。例如,(byte)300 的实际值为 44

C++ 注释:不要在 boolean 类型与任何数值类型之间进行强制类型转换,这样可以防止发生错误。只有极少数的情况才需要将布尔类型转换为数值类型,这时可以使用条件表达式 b ? 1:0

3.5.7 括号与运算符级别

3-4 给出了运算符的优先级。如果不使用圆括号,就按照给出的运算符优先级次序进行计算。同一个级别的运算符按照从左到右的次序进行计算(除了表中给出的右结合运算符外。)例如,由于 && 的优先级比 || 的优先级高,所以表达式

等价于

又因为 += 是右结合运算符,所以表达式

等价于

也就是将 b += c 的结果(加上 c 之后的 b)加到 a 上。

C++ 注释:C C++ 不同,Java 不使用逗号运算符。不过,可以在 for 语句中使用逗号分隔表达式列表。

3-4运算符

运算符优先级

[ ] . ( ) ( 方法调用 )
! ~ ++ -- + (
一元运算 ) - ( 一元运算 ) ( ) ( 强制类型转换 ) new 从右向左

*/ % 从左向右

+– 从左向右

<< >> >>> 从左向右

< <= > >= instanceof 从左向右

== != 从左向右

& 从左向右

^ 从左向右

| 从左向右

&& 从左向右

|| 从左向右

?: 从右向左

= += – = *= /= %= &= |= ^= <<= >>= >>>= 从右向左 

最后

以上就是纯真白羊为你收集整理的java核心技术卷1---运算符的全部内容,希望文章能够帮你解决java核心技术卷1---运算符所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部