Scala的數(shù)學運算、關系和邏輯操作及位操作符
數(shù)學運算
你可以通過中綴操作符,加號(+),減號(-),乘號(*),除號(/)和余數(shù)(%),在任何數(shù)類型上調用數(shù)學方法。以下是一些例子:
51CTO編輯推薦:Scala編程語言專題
當左右兩個操作數(shù)都是整數(shù)類型時(Int,Long,Byte,Short,或Char),/操作符將返回給你商的整數(shù)部分,去掉余數(shù)部分。%操作符指明它的余數(shù)。
- scala> 1.2 + 2.3
- res6: Double = 3.5
- scala> 3 - 1
- res7: Int = 2
- scala> 'b' - 'a'
- res8: Int = 1
- scala> 2L * 3L
- res9: Long = 6
- scala> 11 / 4
- res10: Int = 2
- scala> 11 % 4
- res11: Int = 3
- scala> 11.0f / 4.0f
- res12: Float = 2.75
- scala> 11.0 % 4.0
- res13: Double = 3.0
用%符號得到的浮點數(shù)余數(shù)部分并不遵循IEEE754標準的定義。IEEE754在計算余數(shù)時使用四舍五入除法,而不是截尾除法,因此余數(shù)的計算與整數(shù)的余數(shù)操作會有很大的不同。如果你的確想要IEEE754的余數(shù),可以調用scala.Math里的IEEEremainder,例如:
數(shù)類型還提供了一元前綴+和-操作符(方法unary_+和unary_-),允許你指示文本數(shù)是正的還是負的,如-3或+4.0。如果你沒有指定一元的+或-,文本數(shù)被解釋為正的。一元符號+也存在只是為了與一元符號-相協(xié)調,不過沒有任何效果。一元符號-還可以用來使變量變成負值。舉例如下:
- scala> Math.IEEEremainder(11.0, 4.0)
- res14: Double = -1.0
關系和邏輯操作
- scala> val neg = 1 + -3
- neg: Int = -2
- scala> val y = +3
- y: Int = 3
- scala> -neg
- res15: Int = 2
你可以用關系方法:大于(>),小于(< ),大于等于(>=)和小于等于(< =)比較數(shù)類型,像等號操作符那樣,產生一個Boolean結果。另外,你可以使用一元操作符!(unary_!方法)改變Boolean值。以下是一些例子:
邏輯方法,邏輯與(&&)和邏輯或(||),以中綴方式帶Boolean操作數(shù)并產生Boolean結果。如:
- scala> 1 > 2
- res16: Boolean = false
- scala> 1 < 2
- res17: Boolean = true
- scala> 1.0 < = 1.0
- res18: Boolean = true
- scala> 3.5f >= 3.6f
- res19: Boolean = false
- scala> 'a' >= 'A'
- res20: Boolean = true
- scala> val thisIsBoring = !true
- thisIsBoring: Boolean = false
- scala> !thisIsBoring
- res21: Boolean = true
與Java里一樣,邏輯與和邏輯或有短路:short-circuit的概念:用這些操作符建造的表達式僅評估最少能決定結果的部分。換句話說,邏輯與和邏輯或表達式的右手側部分在左手側部分能決定結果時就不再被評估了。舉個例子,如果邏輯與表達式的左手側計算結果為false,那么表達式的結果將注定是false,因此右手側部分不再做評估。與之類似,如果邏輯或表達式的左手側部分計算結果為true,那么表達式的結果將必然是true,于是右手側部分不再被計算。下面是一些例子:
- scala> val toBe = true
- toBe: Boolean = true
- scala> val question = toBe || !toBe
- question: Boolean = true
- scala> val paradox = toBe && !toBe
- paradox: Boolean = false
***個表達式中,pepper和salt都被調用,但第二個里,只有salt被調用。因為salt返回false,所以就沒必要調用pepper了。
- scala> def salt() = { println("salt"); false }
- salt: ()Boolean
- scala> def pepper() = { println("pepper"); true }
- pepper: ()Boolean
- scala> pepper() && salt()
- pepper
- salt
- res22: Boolean = false
- scala> salt() && pepper()
- salt
- res23: Boolean = false
注意
或許你會想知道如果操作符都只是方法的話短路機制是怎么工作的呢。通常,進入方法之前所有的參數(shù)都會被評估,因此方法怎么可能選擇不評估他的第二個參數(shù)呢?答案是因為所有的Scala方法都有延遲其參數(shù)評估乃至取消評估的設置。
位操作符
Scala讓你能夠使用若干位方法對整數(shù)類型的單個位執(zhí)行操作。有:按位與運算(&),按位或運算(|)和按位異或運算(^)。按位異或方法對它的操作數(shù)執(zhí)行互斥或:exclusive or操作。一致的位產生0。差異的位產生1。因此0011 ^ 0101產生0110。一元按位取補操作符(~,方法unary_~),反轉它的操作數(shù)的每一位。例如:
***個表達式,1 & 2,與運算了1(0001)和2(0010)的每一個位,并產生了0(0000)。第二個表達式,1 | 2,對同樣的操作數(shù)的每一個位執(zhí)行或運算,并產生3(0011)。第三個表達式,1 ^ 3,異或1(0001)和3(0011)的每一個位,產生2(0010)。***的表達式,~1,轉換了1(0001)的每一個位,產生了-2,二進制看起來是1111 1111 1111 1111 1111 1111 1111 1111 1111 1110。
- scala> 1 & 2
- res24: Int = 0
- scala> 1 | 2
- res25: Int = 3
- scala> 1 ˆ 3
- res26: Int = 2
- scala> ~1
- res27: Int = -2
Scala整數(shù)類型還提供了三個位移方法:左移(< < ),右移(>>)和無符號右移(>>>)。使用在中綴操作符方式時,位移方法會按照右側指定的整數(shù)值次數(shù)逐位移動左側的整數(shù)。左移和無符號右移在移動的時候填入零。右移則在移動時填入左側整數(shù)的***位(符號位)。舉例如下:
- scala> -1 >> 31
- res38: Int = -1
- scala> -1 >>> 31
- res39: Int = 1
- scala> 1 < < 2
- res40: Int = 4
二進制的-1是1111 1111 1111 1111 1111 1111 1111 1111。***個例子里,-1 >> 31,-1被右移了31個位。由于Int包括32位,這個操作實際就是把最左側的一位移到了最右側。數(shù)字類型的最左側位是符號位。如果最左側位是1,數(shù)字就是負的,如果是0,數(shù)字就是正的。由于>>方法在不斷右移的時候填入的是1,-1最左側的一位是1,導致結果與原來左側的數(shù)字一模一樣,32位個1,或者說是-1。第二個例子里,-1 >>> 31,最左側的位再一次不斷向右移直至最右側的位置,但是這次填入的是0。因此這次的結果是二進制的0000 0000 0000 0000 0000 0000 0000 0001,或者說是1。***一個例子里,1 < < 2,左操作數(shù),1,被向左移動2個位置(填入0),產生結果是二進制的0000 0000 0000 0000 0000 0000 0000 0100,或者說是4。
【相關閱讀】
- Scala的操作符:任何方法都可以是操作符
- Scala的基本類型及文本化
- Scala程序及其Application特質
- Scala程序中的分號推斷和Singleton對象
- 學習Scala類的定義,字段和方法