Bitwise Operators 位運算符

When working with any of the integer types, you have operators that can work directly with the bits that make up the integers. This means that you can use masking techniques to get at individual bits in a number. The bitwise operators are

& ("and") | ("or") ^ ("xor") ~ ("not")

These operators work on bit patterns. For example, if n is an integer variable, then

int fourthBitFromRight = (n & 8) / 8;

gives you a 1 if the fourth bit from the right in the binary representation of n is 1, and 0 if not. Using & with the appropriate power of 2 lets you mask out all but a single bit.

在對整數類型進行處理的時,還有能夠直接處理構成整數的各個位的運算符。這意味著你可以使用掩碼技術來處理一個數字中的各個獨立位。這些位運算符是:

& ("與") | ("或") ^ ("異或") ~ ("非")

這些運算符工作在比特形式下。例如,如果n是一個整型變量,那么

int fourthBitFromRight = (n & 8) / 8;

這條語句將在n的二進制表示從右起第四位是1時得出結果1,否則為0。使用&符號搭配適當的2的指數冪可以使你屏蔽某一個位以外的所有位。

NOTE 注釋

?

When applied to boolean values, the & and | operators yield a boolean value. These operators are similar to the && and || operators, except that the & and | operators are not evaluated in "short circuit" fashion. That is, both arguments are first evaluated before the result is computed.

當應用于布爾值時,&和|運算將產生一個布爾值。這些運算符和&&以及||運算符是類似的,但是&和|并不以短路形式運算。也就是說,兩個參數在結果算出之前就參與運算。(譯者注,參見http://www.itsway.net/java/java020505.aspx

There are also >> and << operators, which shift a bit pattern to the right or left. These operators are often convenient when you need to build up bit patterns to do bit masking:

int fourthBitFromRight = (n & (1 << 3)) >> 3;

Finally, a >>> operator fills the top bits with zero, whereas >> extends the sign bit into the top bits. There is no <<< operator.

還有>>和<<運算符,可以向左或者向右移動一位。這些運算符在你需要通過位模式來執(zhí)行按位掩碼時是非常方便的,例如:

int fourthBitFromRight = (n & (1 << 3)) >> 3;

最后,>>>運算符用0填寫頭兩位,而>>把符號為增加到頭一位。沒有<<<運算符。

CAUTION 注意

?

The right-hand side argument of the shift operators is reduced modulo 32 (unless the left-hand side is a long, in which case the right-hand side is reduced modulo 64). For example, the value of 1 << 35 is the same as 1 << 3 or 8.

移位運算符右邊的參數被減少到32(除非左邊的參數較長,這種情況下,右邊的較少到64)。例如,1<<35的值和1<<3或者1<<8是一樣的。

C++ NOTE C++注釋

?

In C/C++, there is no guarantee as to whether >> performs an arithmetic shift (extending the sign bit) or a logical shift (filling in with zeroes). Implementors are free to choose whatever is more efficient. That means the C/C++ >> operator is really only defined for non-negative numbers. Java removes that ambiguity.

在C/C++中,并不保證>>進行的是算術移位(擴展符號位)還是邏輯移位(以0填充)。設備可以在二者中選擇更有效的操作。這就意味著C/C++中的>>運算符的確僅僅是為非負數定義的。Java去除了這種歧義性。

Mathematical Functions and Constants 數學函數與常量

The Math class contains an assortment of mathematical functions that you may occasionally need, depending on the kind of programming that you do.

To take the square root of a number, you use the sqrt method:

Math類包含一組你有時會用到的數學函數,這取決于你所編程序的類型。要計算一個數字的平方根,需要使用sqrt方法:

double x = 4;

double y = Math.sqrt(x);

System.out.println(y); // 打印 2.0

NOTE 注釋

?

There is a subtle difference between the println method and the sqrt method. The println method operates on an object, System.out, defined in the System class. But the sqrt method in the Math class does not operate on any object. Such a method is called a static method. You can learn more about static methods in Chapter 4.

println方法和sqrt方法有一個微妙的差別。println方法對一個對象進行操作,即System類中定義的System.out。但是Math類中的sqrt方法并不對任何對象進行操作。這樣的方法稱作靜態(tài)方法。你可在第四章中學習更多有關靜態(tài)方法的知識。

The Java programming language has no operator for raising a quantity to a power: you must use the pow method in the Math class. The statement

double y = Math.pow(x, a);

sets y to be x raised to the power a (xa). The pow method has parameters that are both of type double, and it returns a double as well.

Java語言沒有指數冪運算符,你需要使用Math類中的pow方法。語句

double y = Math.pow(x, a);

將y的值設置為x的a次冪。pow方法的兩個參數都應該是double類型,且返回值也是double類型。

The Math class supplies the usual trigonometric functions

Math類提供了常用的三角函數:

Math.sin

Math.cos

Math.tan

Math.atan

Math.atan2

and the exponential function and its inverse, the natural log:

以及指數函數及其逆運算——自然對數:

Math.exp

Math.log

Finally, two constants denote the closest possible approximations to the mathematical constants p and e:

最后,介紹兩個與數學常量p 和 e的值非常近似的常量:

Math.PI

Math.E

TIP提示

?

Starting with JDK 5.0, you can avoid the Math prefix for the mathematical methods and constants by adding the following line to the top of your source file:

從JDK5.0開始,你可以在源文件起始處使用如下代碼來避免每次使用數學方法和常量的Math前綴。

import static java.lang.Math.*;

For example,

例如:

System.out.println("The square root of \u03C0 is " + sqrt(PI));

We discuss static imports in Chapter 4.

我們將在第四章討論靜態(tài)導入。

NOTE注意

?

The functions in the Math class use the routines in the computer's floating-point unit for fastest performance. If completely predictable results are more important than fast performance, use the StrictMath class instead. It implements the algorithms from the "Freely Distributable Math Library" fdlibm, guaranteeing identical results on all platforms. See http://www.netlib.org/fdlibm/index.html for the source of these algorithms. (Whenever fdlibm provides more than one definition for a function, the StrictMath class follows the IEEE 754 version whose name starts with an "e".)

為了獲得最快的性能,Math類中的函數使用計算機浮點運算單元中的例程。如果可預測的結果完全重于快速表現(xiàn),則使用StrictMath類。這個類從“自由分布數學庫”中實現(xiàn)運算,保證各個平臺上的統(tǒng)一的結果。算法源碼參見http://www.netlib.org/fdlibm/index.html。不論何時fdlibm提供對一個函數的多種定義,StrictMath類始終遵循以“e”開始命名的IEEE 754版本。

Conversions Between Numeric Types 數字類型之間的轉換

It is often necessary to convert from one numeric type to another. Figure 3-1 shows the legal conversions.

在多種數字類型之間進行轉換是常有的事,圖3-1說明了合法的轉換:

3-1 數字類型之間的合法轉換

The six solid arrows in Figure 3-1 denote conversions without information loss. The three dotted arrows denote conversions that may lose precision. For example, a large integer such as 123456789 has more digits than the float type can represent. When the integer is converted to a float, the resulting value has the correct magnitude but it loses some precision.

圖3-1中的六個實箭頭表示無信息丟失的轉換。三個虛箭頭表示可能丟失精度的轉換。例如,一個大的整型數字,如123456789,其位數多于浮點型能夠表示的位數。當這個整型數轉換成浮點型時,結果值仍然很大,但是丟失了精度。

int n = 123456789;

float f = n; // f is 1.23456792E8

When two values with a binary operator (such as n + f where n is an integer and f is a floating-point value) are combined, both operands are converted to a common type before the operation is carried out.

當兩個數字和一個二進制運算符結合在一起(例如n+f中,n是一個整數,而f是一個浮點數),兩個操作數都會在運算之前被轉換為通用類型。

  • If either of the operands is of type double, the other one will be converted to a double.
  • Otherwise, if either of the operands is of type float, the other one will be converted to a float.
  • Otherwise, if either of the operands is of type long, the other one will be converted to a long.
  • Otherwise, both operands will be converted to an int.
  • 如果兩個操作數有一個是double型,另一個轉換為double型。
  • 否則,如果兩個操作數有一個為float型,則另一個轉換為float型。
  • 否則,如果兩個操作數有一個為long型,則另一個轉換為long型。
  • 否則,兩個操作數都被轉換為整型。

Casts

In the preceding section, you saw that int values are automatically converted to double values when necessary. On the other hand, there are obviously times when you want to consider a double as an integer. Numeric conversions are possible in Java, but of course information may be lost. Conversions in which loss of information is possible are done by means of casts. The syntax for casting is to give the target type in parentheses, followed by the variable name. For example:

在前面的章節(jié)中,你可以看到整型值在需要的時候可以自動轉換為double型,另一方面,有時你也希望把double型轉換為整型。在Java中,數字類型的轉換是允許的,但是丟失信息也是自然的。丟失信息的轉換是依靠強制轉換來完成的。強制轉換的語句是在變量名前加上由圓括號括起來的目標類型,例如:

double x = 9.997;

int nx = (int) x;

Then, the variable nx has the value 9 because casting a floating-point value to an integer discards the fractional part.

這樣,變量nx的值就是0,因為浮點型向整型的強制轉換舍棄了小數部分。

If you want to round a floating-point number to the nearest integer (which is the more useful operation in most cases), use the Math.round method:

如果你想把一個浮點數四舍五入成最接近的整數(在大多數情況下,這是更有用的操作),使用Math.round方法:

double x = 9.997;

int nx = (int) Math.round(x);

Now the variable nx has the value 10. You still need to use the cast (int) when you call round. The reason is that the return value of the round method is a long, and a long can only be assigned to an int with an explicit cast because there is the possibility of information loss.

現(xiàn)在,變量nx的值就是10了。在你調用round方法時,你還是需要進行強制轉換(int)。原因是round方法的返回值類型是long,而long類型在給int變量賦值時,由于可能產生信息丟失,所以必須采用顯式轉換。

CAUTION注意

If you try to cast a number of one type to another that is out of the range for the target type, the result will be a truncated number that has a different value. For example, (byte) 300 is actually 44.

如果你試圖將某種類型的數字轉換為比原類型范圍小的目標類型,結果將被截斷,產生一個不同的值,例如(byte) 300 的結果實際上是44。

C++ NOTE C++注釋

You cannot cast between boolean values and any numeric type. This convention prevents common errors. In the rare case that you want to convert a boolean value to a number, you can use a conditional expression such as b ? 1 : 0.

你不能在布爾型和數字類型之間進行轉換。這種轉換將產生常見錯誤。極少數情況下,你希望將布爾值轉換為一個數字,此時你可以使用條件表達式,例如b?1:0

Parentheses and Operator Hierarchy 圓括號和運算優(yōu)先級

Table 3-4 shows the precedence of operators. If no parentheses are used, operations are performed in the hierarchical order indicated. Operators on the same level are processed from left to right, except for those that are right associative, as indicated in the table. For example, because && has a higher precedence than ||, the expression

Table 3-4. Operator Precedence

Operators

Associativity

[] . () (method call)

Left to right

! ~ ++ -- + (unary) – (unary) () (cast) new

Right to left

* / %

Left to right

+ -

Left to right

<< >> >>>

Left to right

< <= > >= instanceof

Left to right

== !=

Left to right

&

Left to right

^

Left to right

|

Left to right

&&

Left to right

||

Left to right

?:

Right to left

= += -= *= /= %= &= |= ^= <<= >>= >>>=

Right to left

表3-4展示了運算符的優(yōu)先級。如果沒有使用括號,運算符將按照表中顯示的優(yōu)先級進行運算。除了表中指明的右結合的運算符,同一級別的運算符自左向右運算。例如,&&和優(yōu)先級高于||,表達式

a && b || c

means等于

(a && b) || c

Because += associates right to left, the expression

由于+=自右向左結合,表達式

a += b += c

means等于

a += (b += c)

That is, the value of b += c (which is the value of b after the addition) is added to a.

也就是b+=c的值(即第一次加法后b的值)再加到a上。

C++ NOTE C++注釋

Unlike C or C++, Java does not have a comma operator. However, you can use a comma-separated list of expressions in the first and third slot of a for statement.

與C或C++不同,Java沒有逗號運算符,但是你可以在一個for語句中的第一個和第三個位置使用一個逗號分隔的表達式。

C語言中的逗號運算符:

C語言中逗號“,”也是一種運算符,稱為逗號運算符。 其功能是把兩個表達式連接起來組成一個表達式, 稱為逗號表達式。
其一般形式為: 表達式1,表達式2 其求值過程是分別求兩個表達式的值,并以表達式2的值作為整個逗號表達式的值。
void main(){
int a=2,b=4,c=6,x,y;
y=(x=a+b),(b+c);
printf("y=%d,x=%d",y,x);
}
a<--2,b<--4,c<--6,x<--0,y<--0
x<--a+b,y<---b+c
本例中,y等于整個逗號表達式的值,也就是表達式2的值,x是第一個表達式的值。對于逗號表達式還要說明幾點:
1.逗號表達式一般形式中的表達式1和表達式2 也可以又是逗號表達式。例如: 表達式1,(表達式2,表達式3) 形成了嵌套情形。因此可以把逗號表達式擴展為以下形式: 表達式1,表達式2,…表達式n 整個逗號表達式的值等于表達式n的值。
2.程序中使用逗號表達式,通常是要分別求逗號表達式內各表達式的值,并不一定要求整個逗號表達式的值。
3.并不是在所有出現(xiàn)逗號的地方都組成逗號表達式,如在變量說明中,函數參數表中逗號只是用作各變量之間的間隔符。
以上是摘抄來的 我本人覺得自己最常使用逗號運算符是在
for循環(huán)里
for (i = 0, j = 0; i < 3 && j < 3; i++, j+=2) {
printf("i = %d, j = %d",i,j);
}

Enumerated Types 枚舉類型

Sometimes, a variable should only hold a restricted set of values. For example, you may sell clothes or pizza in four sizes: small, medium, large, and extra large. Of course, you could encode these sizes as integers 1, 2, 3, 4, or characters S, M, L, and X. But that is an error-prone setup. It is too easy for a variable to hold a wrong value (such as 0 or m).

有時候,一個變量需要僅保存一組有限值的集合。例如,你可能出售四種尺寸的衣服或者匹薩:小號、中號、大號和特大號。當然,你可以給這四種型號編號為1,2,3,4或者S,M,L,X。但這是一個具有錯誤傾向的設置。變量很可能會承載一個錯誤的值(比如0或者m)。

Starting with JDK 5.0, you can define your own enumerated type whenever such a situation arises. An enumerated type has a finite number of named values. For example,

從JDK5.0開始,你可以在遇到這種情況時定義自己的枚舉類型。一個枚舉類型具有有限個數的命名變量。例如:

enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };

Now you can declare variables of this type:

現(xiàn)在,你可以定義這種類型的變量:

Size s = Size.MEDIUM;

A variable of type Size can hold only one of the values listed in the type declaration or the special value null that indicates that the variable is not set to any value at all.

一個Size類型的變量只能承載Size類型中聲明的一個值,或者承載一個特殊值null來表示這個變量沒有被設置任何值。

We discuss enumerated types in greater detail in Chapter 5.

我們將在第五章更詳細的討論枚舉類型。


文章來源:http://x-spirit.spaces.live.com/Blog/cns!CC0B04AE126337C0!314.entry