為什麼負數的取餘計算各個程式設計語言結果不統一?

來源:互聯網
上載者:User

回複內容:

帶正負號的整數的除法與餘數 數學上都正確,這個定義本來就有好幾個
比如按
或者按
IEEE標準是則是,然而round標準也有好幾個。。。
如果round是IEEE預設的round to the nearest,從標準的角度似乎應該是3。。。但IEEE好像也沒說其他的round標準不對。。。

PS:很多語言乾脆提供了兩個函數,rem和mod就是商向0或負無窮方向取整的選擇,c從c99開始規定向0取整,py則規定向負無窮取整,選擇而已,無所謂對錯就算是相同語言不同編譯器也會不一樣的。

在我發現這個問題之後,每當我更新IDE/編譯器的時候都會用我的測試程式跑一遍,看看是不是和上個版本有什麼不同。

有的時候一些小改動很坑的。

PS:有時候也不行,不能保證測試結果是唯一的。問題的關鍵在於商是向負無窮取值還是向0取值 -7/10=0....-7
or
-7/10=-1....3
其他語言我不清楚,貌似c11規定向0取值關於負數的餘數,樓上很多網友已經闡述了純數學概念上的意義。我想從另一個角度說說我的看法。先明確一點:我們討論的是“被除數”(分子)是負整數,而除數(分母)是正整數的情況。

先看一個例子: (-17) mod 5 =?

答案一: (-17) = (-3)*5 + (-2),所以餘數是 -2 。

答案二: (-17) = (-4)*5 + (+3),所以餘數是 +3 。

首先,從“純數學”概念上說,兩個答案都“對”,就好像解方程的時候出現“複數解”一樣,也是一個解。所以各種編譯器按照各自的邏輯來產生餘數。

但是,從人類思維角度上說,“負數”的起源是因為“不足、欠缺”,使用負數是為了知道有多欠缺,然後去補救。從這個角度才能正確理解“負數的餘數”的實際意義(區別於純數學概念)。

打個比方,你和另外5個同學住在宿舍裡,你很勤快,那5個人很懶,讓你幫忙買早餐,比如說,油條、豆漿 …… 你提著他們的早餐回來,對他們說:“一共17塊錢。”就是說,他們5個人一共欠你17元。平均每人給你 17/5=3.4元。

於是他們就翻箱倒櫃 —— 不是沒有錢,而是在找零錢,每人都要拿0.4元,嗯,各位看官不妨找找自己身上有沒有4毛錢 …… 結果就是,都找不到零錢,怎麼辦?於是有兩種辦法:

辦法一:每人給你3塊錢,但是總共還欠你2塊錢,餘數= -2

辦法二:每人給你4塊錢,但是你要給回他們3塊錢,餘數 = +3

現在問題是:各位作為人類,傾向於採用哪一個辦法?

上面說了,人類之所以使用負數,是為了知道“不足”,然後進行補救。現在既然欠了錢要還,我想那5位同學都會給你4塊錢,倒不是說他們是為了給你3塊錢跑腿費,而是他們想“了(liao)了(le)這筆賬”,他們不想5個人 每人都欠你0.4元的人情(何況你還真的跑腿了),既然都還錢了,為什麼還要留一筆“遺留問題”呢?

所以, 從人類思維習慣和實際需要來說 (再說一遍:區別於純數學概念),無論被除數(分子)是正數還是負數,餘數都應該取正數,這樣才符合人類的思維習慣和實際需要。

題外話:就好像除數(分母)通常是正數一樣,如果用一個負數來做除數(分母),人們會覺得很彆扭,很難理解。

其實,如果允許餘數可以是負數的話,那麼 23%5 同樣有兩個答案,可以看作 +3,也可以是 -2,但我相信沒有人會用 -2,第一反應肯定是用 +3 。

現在回到題主的問題: (-7)%10=? 是 +3 還是 -7 ?

如果說人話,就是:現在欠你7塊錢,由10個人來還,怎麼辦?

辦法一:每人還你一塊錢,結果多出3塊錢,餘數=+3

辦法二:每人還給你 0元,餘數 = -7 ,結果最後,一切照舊,依然欠你7塊錢 ……
數學語言說:向負無窮取值還是向0取值 ……

==========分割線==========分割線==========分割線==========分割線==========

說到這裡,可能有人說,數學不是憑情感、看習慣的,數學是嚴謹的。

我非常贊同這個觀點,對於數學這種推崇嚴密和嚴謹的科學,同樣的運算元、同樣的運算子,必然得到同樣的運算結果。那麼,餘數這種“可正可負”的“雙重標準”是致命的 Fatal Error ,會摧毀數學大殿的根基。試想一下,-7伏和+3伏是兩個截然相反的脈衝訊號,足以讓太空梭掉進茫茫大海了……

還是以 (-7)%10 為例。同餘定理是數學的基礎定理之一,中學生都懂,我們來看看:

13 %10 = 3
(13+10)%10= 3
(13+20)%10= 3
(13-10)%10= 3
(13-20)%10=(-7)%10=? —— 問題來了。

顯然,根據餘數定理,答案無疑就是+3 ,而不是 -7 。這與我的上述觀點互相印證。

如果認為 (-7)%10=-7 的話,那麼連中學生都懂的餘數定理就不成立了,數學變得如此脆弱,如此不堪一擊。

餘數定理是電腦表示負數、補數的理論基礎,那些編譯器產生的混亂結果,恰恰說明這些編譯器的開發人員不懂得餘數的概念和意義。畢竟,搞電腦和搞數學是不同的領域。因為數學上一般不關心負數的餘數,數論一般討論的都是正整數。可能是程式員沒有區分開 取餘和模數,百度一下取餘,模數。僅供參考說的好像各個程式設計語言內部是統一的一樣。。

請題主先把cl、gcc、clang、cmake、tc等實現的各主要版本都實驗一遍。。
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.