在Integer類的源碼中,toString方法中調(diào)用getChars方法,getChars方法是獲取數(shù)值對(duì)應(yīng)的字符串,其中有兩個(gè)地方使用了非常巧妙的方式來進(jìn)行除法運(yùn)算和取余運(yùn)算。在計(jì)算機(jī)中,a/b 和 a%b相比較位運(yùn)算,都是比較費(fèi)時(shí)的計(jì)算的。下面來看看jdk中是如何優(yōu)化計(jì)算的
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、禹州網(wǎng)絡(luò)推廣、重慶小程序開發(fā)、禹州網(wǎng)絡(luò)營銷、禹州企業(yè)策劃、禹州品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供禹州建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:jinyejixie.com
// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
思路是這樣:
當(dāng) i >= 65536時(shí),是每兩位取出數(shù)字,i /= 100,例如 i = 567235474,
(1)先取最后兩位 7 和 4 放入buf數(shù)組中,i = 5672354,buf = { , , , , , , , '7', '4'};
(2)再取最后兩位 5 和 4 放入buf數(shù)組中,i = 56723,buf = { , , , , , '5', '4', '7', '4'};
當(dāng) i < 65536 時(shí),跳出循環(huán),采用每一次取出一位數(shù)字,也就是 i /= 10
(3)取最后一位 3 放入buf數(shù)組中,i = 5672,buf = { , , , , '3', '5', '4', '7', '4'};
(4)取最后一位 2 放入buf數(shù)組中,i = 567,buf = { , , , '2', '3', '5', '4', '7', '4'};
(5)取最后一位 7 放入buf數(shù)組中,i = 56,buf = { , , '7', '2', '3', '5', '4', '7', '4'};
(6)取最后一位 6 放入buf數(shù)組中,i = 5,buf = { , '6', '7', '2', '3', '5', '4', '7', '4'};
(7)取最后一位 5 放入buf數(shù)組中,i = 0,buf = { '5', '6', '7', '2', '3', '5', '4', '7', '4'},結(jié)束。
但在jdk中,并不都是直接用 a/b 除法 和 a%c 取余來獲取 商 和 余數(shù)的
1、對(duì)100除法:q = i / 100,直接除法
2、對(duì)100取余:r = i - ((q << 6) + (q << 5) + (q << 2));
推導(dǎo)如下:
? ? ? ?r = i - (q x 100)
? ? ? ?r = i - (q x 64 + q x 32 + q x 4)
? ? ? ?r = i - ((q << 6) + (q << 5) + (q << 2))
3、對(duì)10除法:q = (i x 52429) >>> (16+3);
推導(dǎo)如下:
2 >>> 19 為 524288,
q = (52429 x i) / 524288 = (52428.8 x i + 0.2 x i) >>> (16+3),
i 拆分為兩部分,i = a x 10 + b(保證a, b 均為正數(shù),且 0 <= b <= 9,
q = ((10a + b) x 52428.8 + 0.2b) >>> 19
q = (524288a + 52428.8b + 0.2i) >>> 19
其中,
52428.8b 最大值為52428.8 x 9, 0.2i 最大值為 13107.2
所以,
52428.8b + 0.2i 最大值為 484966.4, 小于 524288 (1 >>> 19), 對(duì)應(yīng)二進(jìn)制會(huì)被右移掉
所以,
q = (a x 524288) >>> 19 + (52428.8 x b + i * 0.2) >>>19 = (a x 524288) >>> 524288 = a
4、對(duì)10取余:r = i - ((q << 3) + (q << 1));
推導(dǎo)如下:
? ? ? ?r = i - (q x 10)
? ? ? ?r = i - (q x 8 + q * 2)
? ? ? ?r = i - ((q << 3 + q << 1)
從這個(gè)方法我們學(xué)到的
1、乘法比除法高效:q = ( i 52429) >>> (16+3); => 約等于q0.1,但i52429是整數(shù)乘法器,結(jié)合位移避免除法
2、充分利用計(jì)算結(jié)果:在獲取r(i%100)時(shí),充分利用了除法的結(jié)果,結(jié)合位移避免重復(fù)計(jì)算
3、位移比乘法高效:r = i – (( q << 6) + ( q << 5) + ( q << 2)); = >等價(jià)于r = i – (q 100)
4、局部性原理之空間局部性
本文標(biāo)題:JDK:Integer.getChars(inti,intindex,char[]buf
分享URL:http://jinyejixie.com/article36/jjpcpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、移動(dòng)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、服務(wù)器托管、ChatGPT、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)