【轉載】計算機程序的思惟邏輯 (3) - 基本運算

運算html

第一節咱們談了經過變量定義數據,上節咱們介紹了給數據賦值,有了初始值以後,能夠對數據進行運算。計算機之因此稱爲"計算"機,是由於發明它的主要目的就是運算。運算有不一樣的類型,不一樣的數據類型支持的運算也不同,本文介紹Java中基本類型數據的主要運算。程序員

  • 算術運算:主要是平常的加減乘除
  • 比較運算:主要是平常的大小比較
  • 邏輯運算:針對布爾值進行運算

算術運算swift

算術運算符有加減乘除,符號分別是+-*/,另外還有取模運算符%,以及自增(++)和自減(--)運算符。取模運算適用於整數和字符類型,其餘算術運算適用於全部數值類型和字符類型,其餘都符合常識,但字符類型看上去比較奇怪,後續文章解釋。c#

減號(-)一般用於兩個數相減, 但也能夠放在一個數前面,例如 -a, 這表示改變a的符號,原來的正數會變爲負數,原來的負數會變爲正數,這也是符合咱們常識的。數組

取模(%)就是數學中的求餘數,例如,5%3是2,10%5是0。spa

自增(++)和自減(--),是一種快捷方式,是對本身進行加一或減一操做。設計

加減乘除大部分狀況和直觀感受是同樣的,都很容易理解,但有一些須要注意的地方,而自增自減稍微複雜一些,下面咱們解釋下。code

加減乘除注意事項htm

運算時要注意結果的範圍,使用恰當的數據類型。兩個正數均可以用int表示,但相乘的結果可能就會超,超出後結果會使人困惑,例如:對象

int a = 2147483647*2; //2147483647是int能表示的最大值

a的結果是-2。爲何是-2咱們暫不解釋,要避免這種狀況,咱們的結果類型應使用long,但只改成long也是不夠的,由於運算仍是默認按照int類型進行,須要將至少一個數據表示爲long形式,即在後面加L或l,下面這樣纔會出現指望的結果:

long a = 2147483647*2L;

另外,須要注意的是,整數相除不是四捨五入,而是直接捨去小數位,例如:

double d = 10/4;

結果是2而不是2.5,若是要按小數進行運算,須要將至少一個數表示爲小數形式,或者使用強制類型轉化,即在數字前面加(double),表示將數字看作double類型,以下所示任意一種形式均可以:

double d = 10/4.0;
double d = 10/(double)4;

以上一些注意事項,我想也沒什麼特別的理由,大概是方便語言設計者實現語言吧。

小數計算結果不精確

不管是使用float仍是double,進行運算時都會出現一些很是使人困惑的現象,好比:

float f = 0.1f*0.1f;
System.out.println(f);

 這個結果看上去,不言而喻,應該是0.01,但實際上,屏幕輸出倒是0.010000001,後面多了個1。換用double看看:

double d = 0.1*0.1;
System.out.println(d);

屏幕輸出0.010000000000000002,一連串的0以後多了個2,結果也不精確。

這是怎麼回事?看上去這麼簡單的運算,計算機怎麼能計算不精確呢?但事實就是這樣,究其緣由,咱們須要理解float和double的二進制表示,後續文章進行分析。

自增(++)/自減(--)

自增/自減是對本身作加一和減一操做,但每一個都有兩種形式,一種是放在變量後,例如a++, a--,另外一種是放在變量前,例如++a, --a。

若是隻是對本身操做,這兩種形式也沒什麼差異,區別在於還有其餘操做的時候。放在變量後(a++),是先用原來的值進行其餘操做,而後再對本身作修改,而放在變量前(++a),是先對本身作修改,再用修改後的值進行其餘操做。例如,快捷運算和其等同的運算分別是:

快捷運算 等同運算
b=a++-1

b=a-1

a=a+1

c = ++a-1

a=a+1

c=a-1

arrA[i++]=arrB[++j]

j=j+1

arrA[i]=arrB[j]

i=i+1

自增/自減是"快捷"操做,是讓程序員少寫代碼的,但遺憾的是,因爲比較奇怪的語法和詭異的行爲,帶給了初學者一些困惑。

比較運算

比較運算就是計算兩個值之間的關係,結果是一個布爾類型(boolean)的值。比較運算適用於全部數值類型和字符類型。數值類型容易理解,但字符怎麼比呢?後續文章解釋。

比較操做符有:大於(>),大於等於(>=),小於(<),小於等於(<=),等於(==),不等於(!=)。

大部分也都是比較直觀的,須要注意的是等於。

首先,它使用兩個等號==,而不是一個等號(=),爲何不用一個等號呢?由於一個等號(=)已經被佔了,表示賦值操做。

另外,對於數組,==判斷的是兩個數組是否是同一個數組,而不是兩個數組的元素內容是否同樣,即便兩個數組的內容是同樣的,但若是是兩個不一樣的數組,==依然會返回false,以下所示:

int[] a = new int[] {1,2,3};
int[] b = new int[] {1,2,3};

// a==b的結果是false

若是須要比較數組的內容是否同樣,須要逐個比較裏面存儲的每一個元素。

邏輯運算

邏輯運算根據數據的邏輯關係,生成一個布爾值true或者false。邏輯運算只可應用於boolean類型的數據,但比較運算的結果是布爾值,因此其餘類型數據的比較結果可進行邏輯運算。

邏輯運算符具體有:

  • 與(&):兩個都爲true纔是true,只要有一個是false就是false
  • 或(|):只要有一個爲true就是true,都是false纔是false
  • 非(!):針對一個變量,true會變成false, false會變成true
  • 異或(^):兩個相同爲false, 兩個不相同爲true
  • 短路與(&&): 和&相似,不一樣之處立刻解釋
  • 短路或 (||):與|相似,不一樣之處立刻解釋

邏輯運算的大部分都是比較直觀的,須要注意的是&和&&,以及|和||的區別。若是隻是進行邏輯運算,它們也都是相同的,區別在於同時有其餘操做的狀況下,例如:

boolean a = true;
int b = 0;
boolean flag = a | b++>0; 

由於a爲true,因此flag也爲true,但b的結果爲1,由於|後面的式子也會進行運算,即便只看a已經知道flag的結果,仍是會進行後面的運算。而||則不一樣,若是最後一句的代碼是:

boolean flag = a || b++>0; 

則b的值仍是0,由於||會"短路",即在看到||前面部分就能夠斷定結果的狀況下,忽略||後面的運算。

這個例子咱們還能夠看出,自增/自減操做帶給咱們的困擾,別的操做都乾乾脆脆,賦值就賦值,加法就加法,比較就比較,它非混在一塊兒,可能會少寫些代碼,但若是使用不當,會使理解困難不少。

運算符優先級

一個稍微複雜的運算可能會涉及多個變量,和多種運算,那哪一個先算,哪一個後算呢?程序語言規定了不一樣運算符的優先級,有的會先算,有的會後算,大部分狀況下,這個優先級與咱們的常識理解是相符的。

但在一些複雜狀況下,咱們可能會搞不明白其運算順序。但這個咱們不用太操心,可使用括號()來表達咱們想要的順序,括號裏的會先進行運算,簡單的說,不肯定順序的時候,就使用括號。

序列號

符號

名稱

結合性(與操做數)

目數

說明

1

.

從左到右

雙目

 

( )

圓括號

從左到右

 

 

[ ]

方括號

從左到右

 

 

2

+

正號

從右到左

單目

 

-

負號

從右到左

單目

 

++

自增

從右到左

單目

前綴增,後綴增

- -

自減

從右到左

前綴減,後綴減

~

按位非/取補運算

從右到左

單目

 

邏輯非

從右到左

單目

!」不能夠與「=」聯用

3

*

從左到右

雙目

 

/

從左到右

雙目

整數除法:取商的整數部分,小數部分去掉,不四捨五入

%

取餘

從左到右

雙目

 

4

+

從左到右

雙目

 

-

從左到右

雙目

 

5

<< 

左移位運算符

從左到右

雙目

 

>> 

帶符號右移位運算符

從左到右

雙目

 

>>> 

無符號右移

從左到右

雙目

 

6

小於

從左到右

雙目

關係運算符「大於」說明

<=

小於或等於

從左到右

雙目

 

大於

從左到右

雙目

 

>=

大於或等於

從左到右

雙目

 

instanceof

肯定某對象是否屬於指定的類

從左到右

雙目

 

7

==

等於

從左到右

雙目

關係運算符「==」說明

!=

不等於

從左到右

雙目

 

8

&

按位與

從左到右

雙目

 

9

|

按位或

從左到右

雙目

 

10

^

按位異或

從左到右

雙目

 

11

&&

短路與

從左到右

雙目

 

12

||

短路或

從左到右

雙目

 

13

? :

條件運算符

從右到左

三目

 

14

=

賦值運算符

從右到左

雙目

 

+=

混合賦值運算符

 

-=

 

*=

 

/=

 

%=

 

&=

 

|=

 

^=

 

<<=

 

>>=

 

>>>=

 

小結

本節咱們介紹了算術運算,比較運算和邏輯運算,但咱們遺留了一些問題,好比:

  • 正整數相乘的結果竟然出現了負數
  • 很是基本的小數運算結果竟然不精確
  • 字符類型怎麼也能夠進行算術運算和比較 

這是怎麼回事呢?

相關文章
相關標籤/搜索