除法如何舍入
7.5 除法如何舍入?
假設(shè)我們用b除a得到商為q余數(shù)為r:
q = a / b;
r = a % b;
我們暫時(shí)假設(shè)b > 0。
我們期望a、b、q和r之間有什么關(guān)聯(lián)?
最重要的,我們期望q * b + r == a,因?yàn)檫@是對(duì)余數(shù)的定義。
如果a的符號(hào)發(fā)生改變,我們期望q的符號(hào)也發(fā)生改變,但絕對(duì)值不變。
我們希望保證r >= 0且r < b。例如,如果余數(shù)將作為一個(gè)哈希表的索引,它必須要保證總是一個(gè)有效的索引。
這三點(diǎn)清楚地描述了整數(shù)除法和求余操作。不幸的是,它們不能同時(shí)為真。
考慮3 / 2,商1余0。這滿足第一點(diǎn)。而-3 /2的值呢?根據(jù)第二點(diǎn),商應(yīng)該是-1,但如果是這樣的話,余數(shù)必須也是-1,這違反了第三點(diǎn)?;蛘?,我們可以通過(guò)將余數(shù)標(biāo)記為1來(lái)滿足第三點(diǎn),但這時(shí)根據(jù)第一點(diǎn)商應(yīng)該是-2。這又違反了第二點(diǎn)。
因此C和其他任何實(shí)現(xiàn)了整數(shù)除法舍入的語(yǔ)言必須放棄上述三個(gè)原則中的至少一個(gè)。
很多程序設(shè)計(jì)語(yǔ)言放棄了第三點(diǎn),要求余數(shù)的符號(hào)必須和被除數(shù)相同。這可以保證第一點(diǎn)和第二點(diǎn)。很多C實(shí)現(xiàn)也是這樣做的。
然而,C語(yǔ)言的定義只保證了第一點(diǎn)和|r|< |b|以及當(dāng)a >= 0且b > 0時(shí)r >= 0。這比第二點(diǎn)或第三點(diǎn)的限制要小,實(shí)際上有些編譯器滿足第二點(diǎn)或第三點(diǎn),但不太常見(如一個(gè)實(shí)現(xiàn)可能總是向著距離0最遠(yuǎn)的方向進(jìn)行舍入)。
盡管有些時(shí)候不需要靈活性,C語(yǔ)言還是足夠可以讓我們令除法完成我們所要做的、提供我們所想知道的。例如,假設(shè)我們有一個(gè)數(shù)n表示一個(gè)標(biāo)識(shí)符中的字符的一些函數(shù),并且我們想通過(guò)除法得到一個(gè)哈希表入口h,其中0 <= h <= HASHSIZE。如果我們知道n是非負(fù)的,我們可以簡(jiǎn)單地寫:
h = n % HASHSIZE;
然而,如果n有可能是負(fù)的,這樣寫就不好了,因?yàn)?/span>h可能也是負(fù)的。然而,我們知道h > -HASHSIZE,因此我們可以寫:
h = n % HASHSIZE;
if(n < 0)
h += HASHSIZE;
同樣,將n聲明為unsigned也可以。
免責(zé)聲明:以上內(nèi)容源自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵犯您的原創(chuàng)版權(quán)請(qǐng)告知,我們將盡快刪除相關(guān)內(nèi)容。