js进制转换

493 阅读4分钟

js进制转换

NumberObject.toString(radix);

// 十进制转换为二进制:
var num = 100;
console.log(num.toString(2));

var num = 0.125; // 十进制数0.125
num.toString(2)  //  '0.001'

// 二进制转十进制:
var num = 1100100;  
console.log(parseInt(num,2));  // 将2进制数转换为10进制
// parseInt() 函数可解析一个字符串,并返回一个整数。  第一个参数填数 第二个参数填当前数是多少进制的数
// parseInt(num,8);   //八进制转十进制
// parseInt(num,16);   //十六进制转十进制
// parseInt(num).toString(8)  //十进制转八进制
// parseInt(num).toString(16)   //十进制转十六进制
// parseInt(num,2).toString(8)   //二进制转八进制
// parseInt(num,2).toString(16)  //二进制转十六进制
// parseInt(num,8).toString(2)   //八进制转二进制
// parseInt(num,8).toString(16)  //八进制转十六进制
// parseInt(num,16).toString(2)  //十六进制转二进制
// parseInt(num,16).toString(8)  //十六进制转八进制

var num = 0.001
parseInt(num,2);  // 0 
// 说明parseInt不能将二进制小数转换为十进制小数

// 具体请看
https://www.jianshu.com/p/e301de533bc3

参考 二进制小数怎么转十进制?

zhidao.baidu.com/question/22…

小数怎么转化为二进制

jingyan.baidu.com/article/eb9…

具体例子

十进制的小数转换为二进制小数,以0.625为例
0.625 * 2   = 1.2510.25  
0.25  * 2   = 0.500.5
0.5   * 2   = 110
从上到下取101  那么小数部分就是101  也就十进制0.625转换为小数为0.101
// 有的小数乘2以后,小数部分一直无法得到0,如0.333333。这种只需要到一定的精确度就行了。

那将二进制0.101怎么转换为十进制呢
先看一个例子:
小数部分从小数点位置开始:1/21/41/81/16。即:1010.1011=>8+2+1/2+1/8+1/16"^"代表幂)
1101.0111=>1*2^3+1*2^2+0*2^1+1*2^0 + 0*2^(-1)+1*2^(-2)+1*2^(-3)+1*2^(-4) 

所以小数部分.101 = 1 * 2^(-1) + 0 * 2^(-2) + 1 * 2^(-3) = 1/2 + 0 + 1/8 = 0.625

// 具体请看
https://www.jianshu.com/p/e301de533bc3

js二进制转十进制程序

/**
* 将二进制小数部分转换为十进制数
* @param binaryFloatPartArr 二进制小数部分中由小数各位组成的数组
*/
function eachBinaryFloatPartToDecimal(binaryFloatPartArr) {
    return binaryFloatPartArr.map((currentValue, index) => {
        return Number(currentValue) * Math.pow(2, (-(index + 1)))
    })
}

/**
* 将二进制小数(包含整数部分和小数部分)转换为十进制数
* @param binaryNum 二进制数(可能是整数,也可能是小数)
*/
function binaryFloatToDecimal(binaryNum) {
    // 如果该二进制只有整数部分则直接用 parseInt(string, radix) 处理
    if (Number.isInteger(binaryNum)) {
        return parseInt(binaryNum, 2)
    } else {
        const binaryFloatNumArr = binaryNum.toString().split(".")

        // 将二进制整数转换为十进制数
        const binaryIntParStr = binaryFloatNumArr[0]
        const decimalIntPartNum = parseInt(binaryIntParStr, 2)

        // 将二进制小数部分转换为十进制数
        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

最后再来解释js中的0.1 + 0.2 === 0.3 为false

// 0.1+0.2 = 0.30000000000000004
var a = (0.1).toString(2)
// '0.0001100110011001100110011001100110011001100110011001101'
var b = (0.2).toString(2)
// '0.001100110011001100110011001100110011001100110011001101'
console.log(a.length)  // 57
console.log(b.length)  // 56

// 0.14*100 = 14.000000000000002
// (0.14).toString(2)
// '0.00100011110101110000101000111101011100001010001111011'

// (0.14).toString(2).length
// 55

**可以看出转换为2进制后的精度的长度是不相同的**
主要还是因为十进制0.1转换为二进制 是无限循环的
就不会像十进制的0.125 转换为二进制后是0.001
// (0.125).toString(2)
// '0.001'
前面其实也有说到  二进制的小数转换为十进制是以1/2 1/4 1/8 1/16 算的
因为计算机是有限的长度  蛋糕不能分得无穷小

其他科普
JavaScript 里的数字是采用 IEEE 754 标准的 64 位双精度浮点数。该规范定义了浮点数的格式,
对于64位的浮点数在内存中的表示,最高的1位是符号位,接着的11位是指数,剩下的52位为有效数字
第0位:符号位, s 表示 ,0表示正数,1表示负数;
第1位到第11位:储存指数部分, e 表示 ;
第12位到第63位:储存小数部分(即有效数字),f 表示,

const bigInt = require("big-integer");
let largeNumber1 = bigInt("756435643634734534563423785643879569067365464564324235345");
let largeNumber2 = bigInt("75643564366756753687325768753897357378673698098546456235345");
console.log(largeNumber1);
console.log(largeNumber2);
console.log(bigInt("756435643634734534563423785643879569