簡體   English   中英

為什么兩個整數之間的除法結果會被截斷?

[英]Why is the division result between two integers truncated?

使用C#中所有經驗豐富的程序員(我認為這來自C)來對除法中的整數進行強制轉換,以獲得小數/雙精度/浮點型結果,而不是整數(實際結果被截斷)。

我想知道為什么這樣實現嗎? 如果兩個數字均為整數,是否有充分的理由截斷結果?

C#的歷史可以追溯到C,因此答案為“為什么在C#中這樣?” 是“為什么在C中這樣子?”的組合 和“是否沒有充分的理由進行更改?”

C的方法是在高級語言和低級操作之間建立相當緊密的對應關系。 處理器通常實現整數除法,以返回商和余數,這兩者與操作數的類型相同。

(所以我的問題是,“為什么類C語言中的整數除法不返回兩個整數 ”,而不是“為什么不返回浮點值?”)

解決方案是為除法和余數提供單獨的運算,每個運算返回一個整數。 在C的上下文中,每個操作的結果都是整數也就不足為奇了。 這通常比浮點運算更准確 考慮從你的評論的例子7 / 3 此值不能用有限的二進制數或有限的十進制數表示 換句話說,今天的電腦, 我們不能准確地代表7 / 3 除非我們使用整數! 該分數的最准確表示是“商2,余數1”。

因此,沒有充分的理由進行更改嗎? 我什么也想不出來,我想到一些改變的充分理由。 其他任何答案都沒有提到Visual Basic(至少在版本6中)具有兩個用於對整數進行除法的運算符: /將整數轉換為double,然后返回double,而\\執行常規的整數算術運算。

在努力使用浮點除法實現二進制搜索算法后,我了解了\\運算符。 這真的很痛苦,整數除法就像呼吸新鮮空氣一樣。 沒有它,在程序的初稿中會涉及很多特殊處理,以覆蓋邊緣情況和一個錯誤。

從這些經驗中,我得出的結論是,使用不同的運算符來划分整數會造成混淆。

另一種選擇是僅執行一個整數運算,該運算總是返回一個double值,並要求程序員截斷它。 這意味着每次要進行整數除法時,都必須執行兩次int-> double轉換,即截斷和double-> int轉換。 還有多少程序員會錯誤地舍入或舍入結果而不是舍棄結果呢? 這是一個更復雜的系統,至少容易出現程序員錯誤,而且速度較慢。

最后,除了二進制搜索,還有許多采用整數算術的標准算法。 一個示例是將對象集合划分為相似大小的子集合。 另一種方法是在1維數組中的索引與2維矩陣中的坐標之間進行轉換。

據我所知,就語言可用性而言,沒有任何替代“ int / int yields int”的方法能幸免於成本效益分析,因此沒有理由改變從C繼承的行為。

結論:

  • 在許多標准算法中,整數除法通常很有用。
  • 當需要整數的浮點除法時,可以通過簡單,簡短和清晰的轉換顯式調用: (double)a / b而不是a / b
  • 其他選擇會給程序員帶來更多的復雜性,並給處理器帶來更多的時鍾周期。

如果兩個數字均為整數,是否有充分的理由截斷結果?

當然; 我可以輕松想到許多這樣的場景。 例如:您有一個大圖像,並且圖像的縮略圖版本在兩個維度上都縮小了10倍。 當用戶單擊大圖像中的一個點時,您希望在縮小的圖像中標識相應的像素。 顯然,您將x和y坐標都除以10。為什么要以十進制表示結果? 縮略圖位圖中的相應坐標將為整數坐標。

雙精度對物理計算非常有用,而十進制對財務計算非常有用,但是我所做的幾乎所有可以完成任何數學運算的計算機工作都完全以整數完成。 我不想因為我做了一些除法就不得不不斷地將雙精度或十進制轉換回整數。 如果您要解決物理或財務問題,那么為什么首先要使用整數? 使用無非是雙打還是小數。 使用整數來解決有限數學問題。

(通常)比在浮點值上計算更快(通常)。 此外,所有其他整數/整數運算( +-* )返回一個整數。

編輯:根據OP的要求,這里有一些補充:

OP的問題是他們將/視為數學意義上的除法,而該語言中的/運算符執行其他操作(這不是數學除法)。 通過這種邏輯,他們也應該質疑所有其他運算( +-* )的有效性,因為這些運算具有特殊的溢出規則,這與數學運算符所期望的不同。 如果這對某人來說很麻煩,他們應該找到另一種語言來執行該人所期望的操作。

至於支持整數的性能差異的主張:當我寫答案時,我只有“民間”知識和“直覺”來支持主張(請注意我的“通常”免責聲明)。 確實正如Gabe所指出的那樣,在某些平台上這並不適用。 另一方面,我發現此鏈接 (第12點)顯示了Intel平台上的混合性能(盡管使用的語言是Java)。

得出的結論是,在執行之前,許多主張和直覺都無法得到證實,直到經過測量並證明是正確的。

是的,如果最終結果需要為整數。 這將取決於要求。

如果確實是這些要求,那么您將不希望存儲小數然后截斷它。 您將浪費內存和處理時間來完成某些已經內置的功能。

運算符被設計為返回與輸入相同的類型。

編輯(評論回復):為什么? 我不是在設計語言,但我會假設大多數時候您會堅持使用開始使用的數據類型,而在其余情況下,將使用什么條件自動假定用戶想要哪種類型? 您會在需要時自動期望一個字符串嗎? (意圖誠意)

如果將int添加到int,則期望獲得一個int。 如果從int減去int,則期望得到int。 如果將一個int乘以一個int,則期望得到一個int。 那么,如果將一個整數除以一個整數,為什么不期望一個整數結果呢? 如果您希望得到一個int,則必須將其截斷。

如果您不想這樣做,則需要先將int轉換為其他類型。

編輯:我還要注意,如果您真的想了解這是為什么,那么您應該開始研究二進制數學的工作原理以及如何在電子電路中實現它。 當然,沒有必要詳細了解它,但是快速瀏覽一下它確實可以幫助您了解硬件的低級細節如何過濾到高級語言的細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM