最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

第 9 講:運(yùn)算符(一):算術(shù)運(yùn)算符

2021-03-25 08:52 作者:SunnieShine  | 我要投稿

Part 1 運(yùn)算符是什么?

為了簡化使用 C# 程序,C# 使用一些類似于數(shù)學(xué)符號的東西來表示一些運(yùn)算,進(jìn)而使得代碼更具有可讀性。

可讀性(Readability)是一種神奇的玩意兒。當(dāng)我們使用英語單詞的時候,我們會覺得更好看懂代碼,畢竟翻譯過來就是實(shí)際的意思了;使用符號反而不一定能明白。但是,從小學(xué)到大,數(shù)學(xué)符號就一直陪伴我們,以至于我們使用運(yùn)算符號反而比一些單詞要更好看懂,所以,運(yùn)算符是一個不可或缺的、表達(dá)復(fù)雜邏輯的一種東西。

C# 里提供了眾多的運(yùn)算符,只有你想不到的,沒有它做不到的。大體上 C# 把運(yùn)算符分成如下若干類:

  • 算術(shù)運(yùn)算符(+、-、*、/%)和正負(fù)號(+、-);

  • 自增自減運(yùn)算符(++、--);

  • 比較運(yùn)算符(>、>=、<<=、==、!=);

  • 邏輯運(yùn)算符(&&、||、&、|^、!)和邏輯元運(yùn)算符(truefalse);

  • 位運(yùn)算符(&|、^、~>>、<<);

  • 賦值運(yùn)算符(=+=、-=、*=/=、%=、&=|=、^=、>>=、<<=);

  • 條件運(yùn)算符(?:);

  • 類型判斷運(yùn)算符(is、as);

  • 溢出校驗(yàn)運(yùn)算符(checkedunchecked);

  • 默認(rèn)運(yùn)算符(default(T));

  • 強(qiáng)制轉(zhuǎn)換運(yùn)算符((T))。

按照順序,我們一個一個來講解。

為了保證調(diào)理清晰,我們按照運(yùn)算符的類型進(jìn)行挨個講解,一種運(yùn)算符用一篇文章來介紹。雖然內(nèi)容可能沒那么多,但是也不必放在一起,這樣文章太長了。

另外,C# 還有一些別的運(yùn)算符號,比如 .、->[]、*、& 等等。這些運(yùn)算符具有特殊用途和用法,且并不一定代表一種“運(yùn)算”,因此我們不單獨(dú)介紹它們,而是通過貫穿教程的方式對這些內(nèi)容進(jìn)行講解;還有一些在之前的內(nèi)容也說過了,所以就不用多說了。

Part 2 沒啥可講的?我不信

算術(shù)運(yùn)算符是運(yùn)算符里最基礎(chǔ)、最容易學(xué)習(xí)的一種運(yùn)算符類型。它不需要專業(yè)編程知識就可以掌握,因?yàn)樗_實(shí)長得很像是數(shù)學(xué)運(yùn)算符。

下面我們來針對上述給的這個例子作介紹。我們先不必考慮除法運(yùn)算,剩下的 +、-* 均和數(shù)學(xué)運(yùn)算的算法沒有區(qū)別。

2-1 整數(shù)取模運(yùn)算

最后一個叫做取模運(yùn)算(%),它雖然寫成數(shù)學(xué)的百分號,但實(shí)際上是除法運(yùn)算。不過取模運(yùn)算是將數(shù)據(jù)進(jìn)行整除,然后取出余數(shù)作為結(jié)果的一種運(yùn)算模型。它等價于下面的這個數(shù)學(xué)公式:

如果我們有式子

a%20%5Cdiv%20b%20%3D%20c%20%5Ctext%7B...%7D%20d%20%5Ctag%7B1%7D

則有數(shù)學(xué)表達(dá)式

a%5C%20%5Ctext%7BMod%7D%5C%20b%20%3D%20d%20%5Ctag%7B2%7D

數(shù)學(xué)運(yùn)算符 Mod?等價于 C# 里的取模運(yùn)算符 %,故上述式子也可以表示為

a%5C%20%5C%25%5C%20b%20%3D%20d%20%5Ctag%7B3%7D

舉個例子:

我們可以輕松地得到,17 除以 3 的結(jié)果是 5,余數(shù)為 2,因此 c 的結(jié)果是 2。

另請注意,當(dāng)取模運(yùn)算符 % 的左側(cè)這個數(shù)我們稱為被取模數(shù)。整數(shù)取模運(yùn)算一定用的是取模運(yùn)算的兩個計算數(shù)值的絕對值。比如 -13 % 7 得當(dāng)成 13 % 7 進(jìn)行計算。而結(jié)果的正負(fù)一定取決于被取模數(shù)。換句話說,只有被取模數(shù)是負(fù)數(shù),結(jié)果才會是負(fù)數(shù);否則怎么著,結(jié)果都是正的。比如 -13 % -7 的結(jié)果一定是 -(13 % 7),即 -6。

2-2 整數(shù)除法運(yùn)算

前面我們說到了取模運(yùn)算,如果說取模運(yùn)算是取出余數(shù)的話,整數(shù)除法運(yùn)算就剛好取的是商。還是看到前面的式子 (1)。這個式子里的 是這個除法式子的商,所以整數(shù)除法運(yùn)算的結(jié)果就是這個 。

C# 里,如果除號 / 兩側(cè)的數(shù)字全部是整數(shù)的話,這個除號就應(yīng)當(dāng)看作是一個整數(shù)除法運(yùn)算。因此,對照前面的例子,3 / 4 的結(jié)果應(yīng)該就是 0,因?yàn)?3 根本不夠被 4 除。如果是 17 / 3 呢?那就是 5 了。

2-3 浮點(diǎn)數(shù)除法運(yùn)算

我們稍微換一下順序。這次浮點(diǎn)數(shù)我們先說除法運(yùn)算,然后再來講解取模運(yùn)算。

當(dāng)我們依舊使用符號 /,但左右兩側(cè)包含浮點(diǎn)數(shù)類型的數(shù)據(jù)的時候,我們就不能套用整數(shù)的除法運(yùn)算了。因?yàn)楦↑c(diǎn)數(shù)是包含小數(shù)部分的,因此整體的結(jié)果就一定會是一個小數(shù)。

C# 里約定,當(dāng)除號 / 的左右兩側(cè)數(shù)值里,至少有一個是 float、doubledecimal 的其一的話,我們就認(rèn)為除法式子里包含小數(shù)。此時,就必須照著浮點(diǎn)數(shù)除法運(yùn)算的規(guī)則(就是這一部分的內(nèi)容)來計算。浮點(diǎn)數(shù)除法和數(shù)學(xué)除法沒有區(qū)別,并不是帶余除法。比如說

由于 3 和 4 均是整數(shù),因此我們無法得到小數(shù)結(jié)果。我們必須得到 0.75 的話,就需要把至少其中一邊改成小數(shù),才能得到小數(shù)結(jié)果。從這則示例里可以看到,我們將 3 強(qiáng)制轉(zhuǎn)換為 double 類型,然后得到一個浮點(diǎn)數(shù)除法運(yùn)算的結(jié)果 0.75,最后賦值給 result 變量。

稍微注意一下的是,小括號沒有必要寫這么多。按照 C# 的習(xí)慣,就算你不打括號,C# 也知道這里 (double)3 / 4 是看成 ((double)3) / 4 而不是 (double)(3 / 4) 的。那么,它們有什么區(qū)別呢?

如果是前者,那么式子就好比是 3.0 / 4 一樣。我們將 3 認(rèn)為是 3.0。雖然 3 和 3.0 在數(shù)學(xué)上沒區(qū)別,但是 C# 里因?yàn)樽置媪款愋偷膯栴},3 是 int 類型(整數(shù)),而 3.0 是 double 類型(浮點(diǎn)數(shù)),因此類型影響著整個運(yùn)算是整數(shù)除法還是浮點(diǎn)數(shù)除法。

而如果是后者,式子就相當(dāng)于是把 3 / 4 的結(jié)果得到后,才轉(zhuǎn)換成 double。前文說到,如果除號的兩側(cè)沒有浮點(diǎn)數(shù)的話,那么結(jié)果就一定是按整數(shù)除法來計算的。那么 3 / 4 的結(jié)果就必然為 0,故式子就好比是 (double)0,即 0.0,沒有意義的轉(zhuǎn)換。

因此,強(qiáng)制轉(zhuǎn)換運(yùn)算符僅和它旁邊這個數(shù)值進(jìn)行“結(jié)合”

這就是浮點(diǎn)數(shù)的除法。

2-4 浮點(diǎn)數(shù)取模運(yùn)算

C# 里除了可以對兩個整數(shù)進(jìn)行取模運(yùn)算,還可以對浮點(diǎn)數(shù)計算。不過概念稍微和整數(shù)的取模運(yùn)算有一點(diǎn)不一樣,但它和數(shù)學(xué)上的余數(shù)運(yùn)算是一樣的算法。

比如 13.3 % 6.3。我們只需要找到一個合適的商,得到 2 這個結(jié)果;那么商乘以除數(shù)可以得到 12.6 這個結(jié)果;那么余數(shù)自然就是 13.3 - 12.6 = 0.7。

Part 3 浮點(diǎn)數(shù)運(yùn)算的精度問題

我們嘗試看一下如下的計算:

我們可以得到的結(jié)果是 0.3。但我們將 float 改成 double

即使我們?nèi)サ?F 字面量后綴

你都不會得到 0.3 這個結(jié)果。實(shí)際上,后面兩個的結(jié)果的小數(shù)位很后面依然有非 0 的數(shù)據(jù)信息。這是因?yàn)槭裁茨兀?span id="s0sssss00s" class="md-plain md-expand">

這并非是 C# 的計算錯誤,而是一個“預(yù)期的”結(jié)果。這我們得回到 IEEE 754 規(guī)范上來。這個規(guī)范規(guī)定和約定,數(shù)據(jù)需要先轉(zhuǎn)換為二進(jìn)制的科學(xué)計數(shù)法表示(即 的格式)。這個式子里,由于一個十進(jìn)制數(shù)要想表達(dá)成這個格式,且內(nèi)存是有限大小的,因此我們無法準(zhǔn)備表達(dá)一個數(shù)值信息,因而會丟失精度。

因此,在存儲和賦值的時候,fg 就已經(jīng)不是真正的 0.1 和 0.2 了,因此結(jié)果必然不是真正的 0.3。因此,我們一定要注意浮點(diǎn)數(shù)的精度問題。

如果需要避免精度錯誤,我們需要用 decimal 類型。

這樣輸出的結(jié)果就肯定是 0.3 了,且不會出現(xiàn)精度的問題。

下面我們來思考一個問題。為什么第一個例子(float 類型運(yùn)算)里,結(jié)果依舊是 0.3 呢?精度會導(dǎo)致數(shù)據(jù)不準(zhǔn)確,但為什么答案依舊是準(zhǔn)確的 0.3 呢?

答案是因?yàn)椋?.1 和 0.2 在存儲的時候,誤差其實(shí)很小,以至于比 float 類型的最低精度還要小,所以算出來看起來沒有問題,但是實(shí)際上答案應(yīng)當(dāng)和第二個例子里顯示的結(jié)果一致(只是誤差比精度還小,因此后續(xù)的部分被舍棄了),因?yàn)榈扔?0.300000... 的后面就全部為 0 了,自然顯示的時候就把全部的小數(shù)部分的 0 全給省略了。

Part 4 字符串的加法

由于 C# 里有一種新的數(shù)據(jù)類型(字符串),這是 C 語言里沒有的數(shù)據(jù)類型,因此它有特殊的運(yùn)算規(guī)則:字符串的加法。

字符串的加法說白了,就是字符串的拼接。

我們通過加法運(yùn)算符 + 來拼接兩個字符串。s + t 將字符串拼接起來,因此輸出的內(nèi)容就是 Hello, Sunnie!。

Part 5 總結(jié)

本節(jié)我們學(xué)習(xí)了基本的五個運(yùn)算符。一定要注意浮點(diǎn)數(shù)和整數(shù)對除法運(yùn)算的不同行為。稍微注意一下,字符串的加法運(yùn)算。


第 9 講:運(yùn)算符(一):算術(shù)運(yùn)算符的評論 (共 條)

分享到微博請遵守國家法律
曲水县| 张北县| 横峰县| 文成县| 定州市| 武强县| 吴忠市| 苏尼特右旗| 万全县| 兴仁县| 商南县| 沙雅县| 长岭县| 鄂伦春自治旗| 邓州市| 金沙县| 晋江市| 白河县| 西城区| 五寨县| 洮南市| 云南省| 宜黄县| 赤壁市| 新密市| 重庆市| 彭水| 榆中县| 内丘县| 建湖县| 乐亭县| 南岸区| 天柱县| 乡城县| 林甸县| 西青区| 额尔古纳市| 姜堰市| 康乐县| 靖宇县| 兰考县|