JS實(shí)現(xiàn)十進(jìn)制與二進(jìn)制的互相轉(zhuǎn)換

javascript 實(shí)現(xiàn)十進(jìn)制與二進(jìn)制之間的轉(zhuǎn)換矗积,在網(wǎng)上能找到不少例子,但很多都少考慮了二進(jìn)制小數(shù)轉(zhuǎn)換為十進(jìn)制的情況敞咧,所以在一些摸索和實(shí)現(xiàn)之后棘捣,想把這種情況的實(shí)現(xiàn)分享給你

需求分析

  • 二進(jìn)制和十進(jìn)制都可能是 整數(shù)浮點(diǎn)數(shù)(小數(shù))
  • 當(dāng)然也可能是正數(shù)和負(fù)數(shù)(因?yàn)樨?fù)數(shù)只需提取一個(gè)負(fù)號(hào)(-),所以該文章以正數(shù)為例)

十進(jìn)制轉(zhuǎn)換為二進(jìn)制

該轉(zhuǎn)換可以用 toString() 方法來實(shí)現(xiàn)

  • toString() 方法返回一個(gè)表示該對(duì)象的字符串

  • 語法:numberObject.toString(radix)

    • 描述:把數(shù)字轉(zhuǎn)換為對(duì)應(yīng)的字符串
    • radix: 可選休建。規(guī)定表示數(shù)字的基數(shù)
  • radix:2 ~ 36 之間的整數(shù)乍恐。若省略該參數(shù),則使用基數(shù) 10测砂。但是要注意茵烈,如果該參數(shù)是 10 以外的其他值,則 ECMAScript 標(biāo)準(zhǔn)允許實(shí)現(xiàn)返回任意值

  • 返回值類型:string

所以砌些,如果想將十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)(整數(shù)和小數(shù)都可以用這種方法)呜投,只需要使用 numberObject.toString(radix) 方法即可

示例:

const decimalNum = 123 
console.log(decimalNum.toString(2))  // "1111011"
const decimalFloatNumber = 123.125
console.log(decimalFloatNumber.toString(2))  // "1111011.001"

因?yàn)?toSting() 返回的是表示該對(duì)象的字符串,所以如果最終結(jié)果是要二進(jìn)制數(shù)值的話存璃,可以再用 Number() 函數(shù)轉(zhuǎn)換一下即可

二進(jìn)制轉(zhuǎn)換為十進(jìn)制

網(wǎng)上例子基本都是用 parseInt(string, radix)仑荐,但如果二進(jìn)制數(shù)有小數(shù)部分,那小數(shù)部分的數(shù)值會(huì)被直接舍去纵东,不符合一些場景的需求設(shè)定

實(shí)現(xiàn)二進(jìn)制(整數(shù)部分&小數(shù)部分)轉(zhuǎn)換為十進(jìn)制的一種方法是:將二進(jìn)制數(shù)分為整數(shù)和小數(shù)兩部分粘招,分別轉(zhuǎn)換為十進(jìn)制數(shù),然后再組合成最終的十進(jìn)制數(shù)值

二進(jìn)制整數(shù)部分轉(zhuǎn)換為十進(jìn)制

這部分很簡單偎球,直接用 parseInt(string, radix) 就可以啦~

  • parseInt() 函數(shù)可解析一個(gè)字符串洒扎,并返回一個(gè)整數(shù)
  • parseInt(string, radix)
    • string: 必需。要被解析的字符串
    • radix : 可選衰絮。表示要解析的數(shù)字的基數(shù)
  • radix:該值介于 2 ~ 36 之間逊笆。如果省略該參數(shù)或其值為 0,則數(shù)字將以 10 為基礎(chǔ)來解析岂傲。如果它以 “0x” 或 “0X” 開頭难裆,將以 16 為基數(shù)。如果該參數(shù)小于 2 或者大于 36镊掖,則 parseInt() 將返回 NaN

二進(jìn)制小數(shù)部分轉(zhuǎn)換為十進(jìn)制

先不用代碼實(shí)現(xiàn)乃戈,整理整理思路,根據(jù)轉(zhuǎn)換原則亩进,就是將小數(shù)點(diǎn)后的每位二進(jìn)制數(shù)都轉(zhuǎn)換成十進(jìn)制數(shù)症虑,然后將各個(gè)位的十進(jìn)制數(shù)加起來,就是完整的小數(shù)部分的十進(jìn)制數(shù)了

比如:1111011.111 的小數(shù)部分為:111

轉(zhuǎn)換過程為:


二進(jìn)制小數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)的計(jì)算過程

對(duì)應(yīng)代碼實(shí)現(xiàn)為:

  • 將二進(jìn)制數(shù)的整數(shù)部分和小數(shù)部分分別取出
    • 先將二進(jìn)制數(shù)轉(zhuǎn)換為字符串
    • split 方法归薛,取出二進(jìn)制數(shù)的整數(shù)部分和小數(shù)部分
const binaryFloatNum = 1111011.111
const binaryFloatNumStr = binaryFloatNum.toString()
console.log(binaryFloatNumStr)  // "1111011.111"
const binaryFloatNumArr = binaryFloatNumStr.split(".")
console.log(binaryFloatNumArr)  // ["1111011", "111"]
  • 將小數(shù)部分轉(zhuǎn)換為十進(jìn)制數(shù)
    • 取出小數(shù)部分
    • 將小數(shù)部分的每位取出
    • 將取出的每位分別轉(zhuǎn)換為十進(jìn)制數(shù)
    • 將轉(zhuǎn)換之后的各個(gè)十進(jìn)制數(shù)相加谍憔,得到由整個(gè)二進(jìn)制小數(shù)部分轉(zhuǎn)換成的十進(jìn)制數(shù)
const binaryFloatPartStr = binaryFloatNumArr[1]  //  "111"
const binaryFloatPartArr = binaryFloatPartStr.split("")  //  ["1", "1", "1"]

/**
* 將 binaryFloatPartArr 數(shù)組中的每項(xiàng)轉(zhuǎn)換為對(duì)應(yīng)的小數(shù)部分的十進(jìn)制數(shù)
* @param decimalArray 二進(jìn)制小數(shù)部分中由小數(shù)各位組成的數(shù)組
*/
function eachBinaryFloatPartToDecimal (binaryFloatPartArr) {
    return binaryFloatPartArr.map((currentValue, index) => {
        return Number(currentValue) * Math.pow(2, (-(index + 1)))
    })
}

const eachDecimalFloatPartNum = eachBinaryFloatPartToDecimal(["1", "1", "1"])
console.log(eachDecimalFloatPartNum)  // [0.5, 0.25, 0.125]

/**
* 將 binaryFloatPartArr 數(shù)組中的每項(xiàng)轉(zhuǎn)換為對(duì)應(yīng)的小數(shù)部分的十進(jìn)制數(shù)
* @param decimalArray 二進(jìn)制小數(shù)部分中由小數(shù)各位組成的數(shù)組
*/
const deciamlFloatPartNum = eachDecimalFloatPartNum.reduce((accumulator, currentValue) => {return accumulator + currentValue})
console.log()  // 0.875

將整個(gè)二進(jìn)制小數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)的程序?yàn)椋?/h2>

ps: 將下面程序復(fù)制到控制臺(tái)可直接運(yùn)行

/**
* 將二進(jìn)制小數(shù)部分轉(zhuǎn)換為十進(jìn)制數(shù)
* @param binaryFloatPartArr 二進(jìn)制小數(shù)部分中由小數(shù)各位組成的數(shù)組
*/
function eachBinaryFloatPartToDecimal(binaryFloatPartArr) {
    return binaryFloatPartArr.map((currentValue, index) => {
        return Number(currentValue) * Math.pow(2, (-(index + 1)))
    })
}

/**
* 將二進(jìn)制小數(shù)(包含整數(shù)部分和小數(shù)部分)轉(zhuǎn)換為十進(jìn)制數(shù)
* @param binaryNum 二進(jìn)制數(shù)(可能是整數(shù)匪蝙,也可能是小數(shù))
*/
function binaryFloatToDecimal(binaryNum) {
    // 如果該二進(jìn)制只有整數(shù)部分則直接用 parseInt(string, radix) 處理
    if (Number.isInteger(binaryNum)) {
        return parseInt(binaryNum, 2)
    } else {
        const binaryFloatNumArr = binaryNum.toString().split(".")

        // 將二進(jìn)制整數(shù)轉(zhuǎn)換為十進(jìn)制數(shù)
        const binaryIntParStr = binaryFloatNumArr[0]
        const decimalIntPartNum = parseInt(binaryIntParStr, 2)

        // 將二進(jìn)制小數(shù)部分轉(zhuǎn)換為十進(jìn)制數(shù)
        const binaryFloatPartArr = binaryFloatNumArr[1].split("")
        const eachDecimalFloatPartNum = eachBinaryFloatPartToDecimal(binaryFloatPartArr)
        const deciamlFloatPartNum = eachDecimalFloatPartNum.reduce((accumulator, currentValue) => { return accumulator + currentValue })
        return decimalIntPartNum + deciamlFloatPartNum
    }
}

console.log(binaryFloatToDecimal(1111011.111))  // 123.875
console.log(binaryFloatToDecimal(1111011))  // 123
console.log(binaryFloatToDecimal(0.111))  // 0.875

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市习贫,隨后出現(xiàn)的幾起案子逛球,更是在濱河造成了極大的恐慌,老刑警劉巖苫昌,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颤绕,死亡現(xiàn)場離奇詭異,居然都是意外死亡祟身,警方通過查閱死者的電腦和手機(jī)奥务,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袜硫,“玉大人氯葬,你說我怎么就攤上這事⊥裣荩” “怎么了溢谤?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長憨攒。 經(jīng)常有香客問我世杀,道長,這世上最難降的妖魔是什么肝集? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任瞻坝,我火速辦了婚禮,結(jié)果婚禮上杏瞻,老公的妹妹穿的比我還像新娘所刀。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜂嗽,像睡著了一般借跪。 火紅的嫁衣襯著肌膚如雪冀墨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼垦沉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛仍劈,可吹牛的內(nèi)容都是我干的厕倍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼贩疙,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼讹弯!你這毒婦竟也來了况既?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤组民,失蹤者是張志新(化名)和其女友劉穎棒仍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邪乍,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年对竣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庇楞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡否纬,死狀恐怖吕晌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情临燃,我是刑警寧澤睛驳,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站膜廊,受9級(jí)特大地震影響乏沸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜爪瓜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一蹬跃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铆铆,春花似錦蝶缀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谅猾,卻和暖如春柄慰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背税娜。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工先煎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巧涧。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓薯蝎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谤绳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子占锯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容