最近寫程序的時(shí)候、碰到一個(gè)問(wèn)題。其實(shí)就是將celing函數(shù)用C++默認(rèn)的除法運(yùn)算(向下取整)表示出來(lái)。所以我打算總結(jié)下整值函數(shù)。
Firth.首先我們要熟悉頂函數(shù)和底函數(shù),最好的方式就是了解他們的圖形。
由于數(shù)學(xué)符號(hào)在這里不好寫出來(lái),我們用floor來(lái)表示底,celing表示頂。
圖形其實(shí)就是以f(x) = x 為分界線,這邊就不畫出來(lái)了。向下取整組成的坐標(biāo)點(diǎn)就是(x, floor(x))
這些剛好就是在f(x) = x下方的,而向上取整則是在上方的。
Tips:
所以從圖像中我們可以發(fā)現(xiàn)一下兩個(gè)等式(位移、奇函數(shù))
1.x – 1 < floor(x) <= x <= celing(x) < x + 1 (可以通過(guò)位移圖像來(lái)得出該不等式)
2.floor(-x) = – celing(x) 或者 celing(-x) = – floor(x) (這個(gè)其實(shí)可以簡(jiǎn)單記為奇函數(shù))
Second.兩條法則(你要細(xì)分成4條我也不反對(duì))
1.floor(x) = n 等價(jià)于 n <= x < n + 1 等價(jià)于 x – 1 < n <= x
2.celing(x) = n 等價(jià)于 n - 1 < x <= n 等價(jià)于 x <= n < x + 1
Tips:
1.其中n是整數(shù),x是實(shí)數(shù)
2.floor(x + n) = floor(x) + n (因?yàn)橛猩厦娣▌t有 floor(x) + n <= x + n < floor(x) + n + 1).
3.但floor(nx) != n*floor(x)
Third.實(shí)數(shù)和整數(shù)之間的關(guān)系,其實(shí)都等價(jià)于一個(gè)頂或底函數(shù)于整數(shù)的關(guān)系。
1.x < n 等價(jià)于 floor(x) < n
2.n < x 等價(jià)于 n < celing(x)
3.x <= n 等價(jià)于 celing(x) <= n
4.n <= x 等價(jià)于 n <= floor(x)
Tips
1.celing相當(dāng)于擴(kuò)大、floor相當(dāng)于縮小
2.取到n,則看能取到最大或者最小,最大取celing、最小floor。
不達(dá)n,則縮小或擴(kuò)大x等式不變。
3.floor(x + y) 等于 floor(x) + floor(y) 或者是 floor(x) + floor(y) + 1
x = floor(x) + {x}, y = floor(y) + {y},then
x + y = floor(x) + floor(y) + {x} + {y},then
floor(x + y) = floor(x) + floor(y) + floor( {x} + {y})
and because 0<={x} < 1 and so do {y},so
0<={x} + {y} <2,so floor({x} + {y}) = 0 or 1
應(yīng)用:
在程序中應(yīng)用之前,我先說(shuō)下一個(gè)等式的證明
celing(n / m) = floor( (n + m – 1) / m)
這里n 、m都是整數(shù),而且m是正整數(shù)。
證明:
因?yàn)閏eling(n /m) – floor(n /m) = celing(n / m – floor(n / m))
= celing(1/m * ( n – m*floor(n / m))) = celing((n mod m) / m)-------------(1)利用了上面兩條法則中Tips的第二點(diǎn)
同理可以得出floor((n + m –1) /m) = floor((n mod m + m – 1) / m)---------- (2)
由(1)可以得到celing((n mod m )/ m) = 1
由(2)可以得到floor((n mod m + m – 1) / m) = 1 (因?yàn)閚 mod m + m – 1 < 2 *m –1)
所以可以一步步向上反推得到上面的公式。(其實(shí)這是一種分而自治的證明思想)
具體在程序中的應(yīng)用例如:
當(dāng)你要在C++中寫如下代碼時(shí)候,而且n 、m都是整數(shù)。
則celing(n * 1.0 / m) = floor( (n – 1) / m) + 1
由于C++中除運(yùn)算就是向下取整,所以
celing(n * 1.0 / m) = (n - 1) / m + 1
那么什么地方用得到,比如你在做大數(shù)運(yùn)算時(shí)侯,要進(jìn)行,分組,要8位一組
然后算出一個(gè)可以分成幾組。可以直接利用這個(gè)原理,而不用再其進(jìn)行函數(shù)的
調(diào)用,比如你在閱讀人家的代碼時(shí)候、有時(shí)候就會(huì)這樣寫。
下次你碰到這種代碼就會(huì)知道什么意思,和為什么能表示成這樣了。