前端开发系列122-进阶篇之Floating point addition

本文简单说明 JavaScript 中常见的进制转换函数以及浮点数计算的注意点。

如何把任意进制的数据转换为十进制?

假设我们有二进制数据110,如果要把该数据转换为十进制数据可以参考下面的处理过程。

ini 复制代码
110  = 1 x 2^(2) + 1 x 2^(1) + 0 x 2^(0) 
     = 4         + 2         + 0 
     = 6

在 JavaScript 语言中,我们可以通过 parseInt方法来处理上面的转换。

parseInt(string, radix)函数将字符串转换为指定进制的整数,进制基数取值区间为[2,36]

其中,函数的第一个参数为要被解析的值。如果参数不是一个字符串,那么会调用toString()来转换为字符串,此外字符串开头的空白符将会被忽略。第二个参数radix的取值范围从 2 到 36,代表该进位系统的数字。parseInt函数的返回值为从给定的字符串中解析出的一个整数,如果radix的取值超出[2,36]的范围或者第一个参数为非空格字符不能转换为数字,那么就返回 NaN

javascript 复制代码
console.log(parseInt("110", 2));
/* 计算过程: */
/* 110  = 1 x 2^(2) + 1 x 2^(1) + 0 x 2^(0)
        = 4         + 2         + 0
        = 6
 */

console.log(parseInt('123', 4));
/* 计算过程 */
/* 123 = 3 x 4^(0) + 2 x 4^(1) + 1 x 4^(2) 
       = 3         + 8         + 16
       = 27
*/

console.log(parseInt('hello', 2));  /* NaN */
console.log(parseInt('', 2));       /* NaN */

ECMAScript 5 规范不再允许 parseInt 函数的实现环境把以0字符开始的字符串作为八进制数值。根据给定的 radix,parseInt函数产生一个由字符串参数内容解析过来的整数值。字符串中开头的空白会被忽略。如果radix没有指定或者为0,参数会被假定以10为基数来解析,如果数值以字符对0x或0X开头,会假定以16为基数来解析。

parseInt函数在具体使用的时候有一些注意点,下面通过代码来简单展示这些注意点。

javascript 复制代码
/* 问题: 为什么得到的结果为1 */
/* 注解:如果 parseInt 遇到的字符不是指定 radix 参数中的数字,
        它将忽略该字符以及所有后续字符,并返回到该点为止已解析的整数值。 */
/* 说明:字符串123abc中,从左向右解析,遇到2的时候解析就停止了 */
console.log(parseInt('123abc', 2)); /* 等价于parseInt('1' , 2) ==> 1*/
console.log(parseInt('123abc', 3)); /* 等价于parseInt('12', 3) ==> 5*/

/* 如果没有指定转换的进制那么就默认以10进制的方式来处理 */
console.log(parseInt('123abc')); /* 123 */

/* 如果第一个参数不是字符串那么会默认调用对应的 toString来转换 */
console.log(parseInt(101, 2)); /* 5 */


console.log(parseInt([7, 2, 3]));
/* 分析代码的处理过程 */
/* (1) [7,2,3]非字符串会默认转换为字符串,[7,2,3].toString() => "7,2,3" */
/* (2) parseInt("7,2,3",10) */
/* (3) parseInt("7",10) */
/* (4) 7 */

JavaScript 语言中的数据表示都是浮点型的,我们在进行转换的时候可能还需要考虑到小数的问题,而且 JavaScript 也是一门典型的0.1 + 0.2 !== 0.3的语言,下面简单通过代码来展示下这些问题。

javascript 复制代码
console.log((6.625).toString(2))  /* 110.101 */

/*110.101 =1 x 2^(2) +1 x 2^(1) +0 x 2^(0) +1 x 2^(-1) +0 x 2^(-2) +1 x 2^(-3)*/
/*        =4         +2         +0         +0.5        +0          +0.125     */
/*        =6.625 */


/* 浮点数字符串转换为二进制数据 */
console.log(parseInt("101.011", 2)) /* 5 说明:小数点后面的数会被截断*/

/* 浮点数 */
let num = 17.235; /* 整数部分:17  小数部分:0.235 */
console.log(num.toString(2));
/* 结果:10001.0011110000101000111101011100001010001111010111 */

/* 二进制表示 */
console.log((0.1).toString(2));
/* 结果:0.0001100110011001100110011001100110011001100110011001101 */
console.log((0.2).toString(2));
/* 结果:0.001100110011001100110011001100110011001100110011001101 */

/* 执行按位相加操作 */
console.log(0.1 + 0.2)          /* 0.30000000000000004 */
console.log(0.1 + 0.2 === 0.3)  /* false */ 
相关推荐
庸俗今天不摸鱼7 分钟前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
QTX187307 分钟前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
黄毛火烧雪下14 分钟前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox24 分钟前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞27 分钟前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行27 分钟前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_5937581028 分钟前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox
掘金一周31 分钟前
金石焕新程 >> 瓜分万元现金大奖征文活动即将回归 | 掘金一周 4.3
前端·人工智能·后端
三翼鸟数字化技术团队1 小时前
Vue自定义指令最佳实践教程
前端·vue.js
Jasmin Tin Wei1 小时前
蓝桥杯 web 学海无涯(axios、ecahrts)版本二
前端·蓝桥杯