语法》第三章 数值

(本文为阮一峰js标准教程的学习笔记,旨在总结该教程中涉及的知识点大纲及个人所做的一些拓展,方便作为“目录”或者“大纲”复习和查漏补缺,详细内容请参见阮一峰教程原文)

第二部分 语法

**********第三章 数值***************

一.概述
1.所有数都是以64位浮点数形式储存的。1与1.0相同(8bit、也就是64位二进制数)
2、JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。
3、由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。
0.1 + 0.2 === 0.3
// false

0.3 / 0.1
// 2.9999999999999996

(0.3 - 0.2) === (0.2 - 0.1)
// false

4、容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算,参见《运算符》一节的”位运算“部分。

二、数值精度
1、国标IEEE754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

第1位:符号位,0表示正数,1表示负数
    第2位到第12位:指数部分
    第13位到第64位:小数部分(即有效数字)

IEEE 754 规定,有效数字第一位默认总是1,不保存在64位浮点数之中。因此,JavaScript 提供的有效数字最长为53个二进制位。

2.精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-(2的53次方-1)到2的53次方-1,都可以精确表示。【内部细节不详】
Math.pow(2, 53)
// 9007199254740992

Math.pow(2, 53) + 1
// 9007199254740992

Math.pow(2, 53) + 2
// 9007199254740994

Math.pow(2, 53) + 3
// 9007199254740996

Math.pow(2, 53) + 4
// 9007199254740996

Math.pow(2, 53)
// 9007199254740992

// 多出的三个有效数字,将无法保存
9007199254740992111
// 9007199254740992000

三.数值范围
1.64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。
分出一半表示负数,则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。
2.指数部分等于或超过最大正值1024,JavaScript 会返回Infinity “正向溢出”;
3.指数等于或超过最小负值-1023(即非常接近0),JavaScript 会直接把这个数转为0,“负向溢出”。

var x = 0.5;

for(var i = 0; i < 25; i++) {
  x = x * x;
}

x // 0

4.js能表示的最大值和最小值,JavaScript 提供Number对象的MAX_VALUE和MIN_VALUE属性表示。

Number.MAX_VALUE // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324

四、数值的表示法
1、使用字面量表示  比如:  0xFF(十六进制)
2、科学计数法,允许字符e或E后跟一个整数,表示*10的多少次方。
3、js自动将数值转科学技术法的几种情况(其他均用字面量形式表示)
(1)小数点前的数字多于21位。

1234567890123456789012
// 1.2345678901234568e+21

123456789012345678901
// 123456789012345680000

(2)小数点后的零多于5个。

// 小数点后紧跟5个以上的零,
// 就自动转为科学计数法
0.0000003 // 3e-7

// 否则,就保持原来的字面形式
0.000003 // 0.000003

五、数值的进制
1.使用字面量时,js对整数提供四种进制。
十进制 没有前导0
十六 前导0x或0X
八 0o 或者0O
二 0b 或者0B

2. 特殊:单独的前导0--前导0表示八进制,处理时很容易造成混乱。ES5的严格模式和ES6,已经废除了这种表示法,但是浏览器目前还支持。
通常来说,有前导0的数值会被视为八进制,但是如果前导0后面有数字8和9,则该数值被视为十进制。

0888 // 888 十进制
0777 // 511 被认为是八进制

3.默认js将十六、八、二自动转十(js依赖先导辨认)
4.前导标明进制,又出现不属于该进制数字报错。

六、特殊数值
1、正零和负零
1.1js内部有两个0,+0和-0是等价的/
1.2严格相等+0===-0 +0 -0  0
1.3js中任何一个数都有负值,0不例外;【不讨论NaN】
1.4唯一区别场合:+0和-0当作分母,返回值不相等;
(1/+0)===(1/-0) //false;
原因:一个得到+Infinity 另一个-Infinity

2.NaN
2.1含义:表示非数字
2.2主要出现场景:将字符串转为数字;
2.3一些函数运算结果出现NaN
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN

2.4
0 / 0 // NaN

2.5,NaN不是一种独立的数据类型,而是一种特殊数值,它的数据类型依然属于Number,使用typeof运算符可以看得很清楚。

typeof NaN // ‘number‘

2.6运算规则:
*不等于任何值,包括自身NaN === NaN // false
*由于数组的indexOf方法,内部使用的是严格相等运算符,所以该方法对NaN不成立。

[NaN].indexOf(NaN) // -1
*Boolean(NaN) // 转布尔false
*与任何数包括自己运算都是NaN
*

2.7 判断NaN方法
2.7.1 isNaN方法:遇到NaN或者可以被转成NaN的值返回true;
   *只对数有效,传入其他值自动转。
   *传入字符串也会为true;
   *isNaN返回true可能是NaN,也可能是别的比如字符串.
isNaN(‘Hello‘) // true
// 相当于
isNaN(Number(‘Hello‘)) // true

出于同样的原因,对于对象和数组,isNaN也返回true。

isNaN({}) // true
// 等同于
isNaN(Number({})) // true

isNaN([‘xzy‘]) // true
// 等同于
isNaN(Number([‘xzy‘])) // true

但是,对于空数组和只有一个数值成2.72员的数组,isNaN返回false。

isNaN([]) // false
isNaN([123]) // false
isNaN([‘123‘]) // false

2.7.2使用isNaN之前,最好判断一下数据类型。

function myIsNaN(value) {
  return typeof value === ‘number‘ && isNaN(value);
}

2.7.3判断NaN更可靠的方法是,利用NaN是JavaScript之中唯一不等于自身的值这个特点,进行判断。

function myIsNaN(value) {
  return value !== value;
}

3.Infinity
3.1定义:特殊数值 number类型,不独立成数据类型;
3.2表示无穷
3.3场景:
*正的太大
*负的太小
*非0数值除以0,得Infinity
注意:0/0是NaN

3.4正负之分:
+Infinity表示正无穷 -Infinity表示负无穷

3.5Infinity大于一切数,-Infinity小于一切  不考虑NaN
3.6Infinity与NaN比较,怎么比都返回false;
3.7
1/-0   -Infinity
-1/-0    Infinity
-1/0     -Infinity
1/0     Infinity

3.8正负向溢出,被零除,js都不报错,说明单纯数学运算几乎没有可能抛出错误;

3.9Infinity的四则运算符合无穷的运算规则;【这条不严谨,并非完全符合】
3.10  0*Infinity//NaN 【居然不是0!  】
3.11 null与Infinity计算  null转0 等同于与0计算
3.12 undefined与Infinity计算全部返回NaN
3.13Infinity加上或乘以Infinity,返回的还是Infinity。

Infinity + Infinity // Infinity
Infinity * Infinity // Infinity

Infinity减去或除以Infinity,得到NaN。

Infinity - Infinity // NaN
Infinity / Infinity // NaN

3.14isFinite函数
isFinite函数返回一个boolean
检查是不是一个正常的数值,或者能否转化为正常数值,遇到NaN,Infinity返回false;
isFinite(Infinity) // false
isFinite(-1) // true
isFinite(true) // true
isFinite(NaN) // false

七、与数值相关的全局方法
1.parseInt()
1.1 字符串转整数
1.2 转出来的数会有向下取整的效果:原因是认不出小数点。
1.3要求参数是字符串。
1.4相关问题:
1.4.1 字符串头部带空格无影响;【中间、尾部空格未知】
1.4.2 遇到不能转为数字的字符,返回已经转好的;
1.4.3 参数不是字符串,先转字符再转数字,这会导致一些令人意外的结果。

parseInt(0x11, 36) // 43
// 等同于
parseInt(String(0x11), 36)
parseInt(‘17‘, 36)

1.4.4 字符串的第一个字符不能转化为数字的情况,返回NaN,但是不包括"-123"这样后面跟着数的正负号
1.4.5 parseInt返回值两种可能:  十进制数 NaN
1.4.6 对于那些会自动转化科学技术的情况,parseInt会将科学技术的表示方法视为字符串,最终导致奇怪结果出现。

parseInt(0.0000008) //等同于parseInt(‘8e-‘)//8

1.4.7 涉及进制转换

*parseInt(‘0x10‘)字符串是带前导的数,parseInt会按照相应的进制解析(命中字符串前导后,会用十六进制解读字符串,为十六进制数,然后转成十进制数返回)
*parseInt(‘1000‘,10)第二参默认是十,以十进制解析字符串,除非命中字符串先导或者手动修改这个第二参
*第二个参数是0、undefined和null,则直接忽略。

parseInt(‘10‘, 37) // NaN
parseInt(‘10‘, 1) // NaN
parseInt(‘10‘, 0) // 10
parseInt(‘10‘, null) // 10
parseInt(‘10‘, undefined) // 10

*第二参是整数,这个整数只有在2到36之间,才能得到有意义的结果,超出这个范围,则返回NaN。
*第二参不是数,或者是小数会自动转成整数,该作死用法此处不研究

*指定了解析进制,字符串中出现无意义字符,从最高位返回可转数,最高位如果都转不了,返回NaN
*指定第二参,就按照第二参的进制解析字符串;
未指定第二参,字符串中有先导被命中,按照先导的进制解析;
以上两个都没有,默认十进制解析;
parseInt(‘011‘,2) 会以二进制处理字符串"011" //得到结果是十进制3
parseInt(‘011‘)  不同浏览器不一样,有的能认出先导0,有的认不出来认为是10进制;

*对于八进制的前缀0,加上第一参非字符串转字符串,两个问题在一起就更纠结了
parseInt(011, 2) // NaN
// 等同于
parseInt(String(011), 2)
由于String(011)这一步转为"9",具体过程是识别出其中的先导,以八进制解析数字为十进制数字9,完了转为字符串。

*ES5不再允许将带有前缀0的数字视为八进制数,而是要求忽略这个0。但是,为了保证兼容性,大部分浏览器并没有部署这一条规定。

2.parseFloat方法()
2.1含义:parseFloat方法用于将一个字符串转为浮点数;
2.2遇到不能转为浮点数的字符,则返回已转好的;
2.3自动过滤前导空格,参数字符串首位空格忽略
2.4字符串第一个字符都不能转直接返回NaN
2.5参数不是字符串,先转字符串(自动),再转浮点数
2.6字符串书写符合科学计数法,能被命中(能认得出来),返回的数值会做相应转换。
parseFloat(‘314e-2‘) //3.14
2.7 parseFloat解析过程中遇到首位(+、-),数字0-9,小数点,科学计数法中的指数标记(e或者E)以外字符,就认不出来了

2.8parseFloat()方法对比Number函数。
parseFloat(true)  // NaN
Number(true) // 1

parseFloat(null) // NaN
Number(null) // 0

parseFloat(‘‘) // NaN
Number(‘‘) // 0

parseFloat(‘123.45#‘) // 123.45
Number(‘123.45#‘) // NaN

时间: 2024-10-10 18:24:41

语法》第三章 数值的相关文章

第三章:绑定语法(1)

第三章所有代码都需要启用KO的 ko.applyBindings(viewModel); 功能,才能使代码生效,为了节约篇幅,所有例子均省略了此行代码. 1 visible 绑定 目的 visible绑定到DOM元素上,使得该元素的hidden或visible状态取决于绑定的值. 例子 <div data-bind="visible: shouldShowMessage"> You will see this message only when "shouldSh

标准库》第三章 包装对象和Boolean对象

第三部分  标准库 ***************第三章   包装对象和Boolean对象******************* 一.包装对象的定义[1]有人说,JavaScript语言"一切皆对象",数组和函数本质上都是对象,就连三种原始类型的值--数值.字符串.布尔值--在一定条件下,也会自动转为对象,也就是原始类型的"包装对象". 所谓"包装对象",就是分别与数值.字符串.布尔值相对应的Number.String.Boolean三个原生对象

JavaScript高级程序设计(第3版)第三章读书笔记

第三章  基本概念 ECMAScript中的一切(变量.函数名和操作符)都区分大小写. 标识符是指变量.函数.属性的名字,或者函数的参数. 标识符的组成规则是:第一个字符必须是一个字母.下划线(_)或一个美元符号($):其他字符可以是字母.下划线.美元符号或数字. ECMAScript标识符采用驼峰大小写格式. ECMAScript注释包括单行注释(//)和块级注释(/*  *  */). ECMAScript 5引入了严格模式的概念,严格模式是为JavaScript定义了一种不同的解析与执行模

Javascript高级程序设计——第三章:基本概念

javascript高级程序设计——第三章:基本概念 一.语法 EMCA-262通过叫做ECMAScript的“伪语言”为我们描述了javascript实现的基本概念 javascript借鉴了C的语法,区分大小写,标示符以字母.下划线.或美元符号($)开头,注释可以用 // 或者/* */ 严格模式: ECMAScript 5引入了严格模式,在严格模式下不确定的行为将得到处理,通过在顶部添加 “use strict”来启用严格模式: function fuc(){ "use strict&qu

Welcome to Swift (苹果官方Swift文档初译与注解二十一)---140~147页(第三章--集合类型)

第三章 Collection Types (集合类型) 在Swift中,提供了两种集合类型用来存储一组值:数组和字典.数组有序的存储相同类型的值;字典存储无序的相同类型的值.字典可以通过唯一的标识(就是所说的键)来查询和访问. 在Swift中,数组和字典总是要清晰的标明他们存储数据的类型.这就意味着不可以将错误的类型插入到数组或字典中.同时也意味着你是明确了解你要遍历的数组或字典里面数据的类 型.在Swift中,集合要显式的声明类型来保证在开发中都会明确的知道它能处理的数据类型. 注意点: 在S

PHP与MYSQL程序设计【第四版】 第三章随笔——(1)

第三章PHP基础 (3.1——3.5) 3.1  在WEB页面中嵌入PHP代码 默认语法:<?php ?> 短标签:<? ?>或<?="";?>——不推荐 脚本:<script language="php"></script> ASP风格:<% %> 3.2 为代码添加注释 单行C++语法:// shell语法:# 多行C语法:/* This That */ 3.3 向浏览器输出数据 print

第三章 MySQL高级查询(一)

第三章 MySQL高级查询(一) 一.SQL语言的四个分类 1.       DML(Data Manipulation Language)(数据操作语言):用来插入,修改和删除表中的数据,如INSERT,UPDATE,DELECT. 2.       DDL(Data Definition Language)(数据定义语言):创建或删除数据库对象操作,有CREATE,DROP,ALTER三个语法组成. 3.       DQL (STructured Query Language)(数据查询语

JavaScript学习笔记(第一章——第三章)

说明 参考资料:<JavaScript高级程序设计(第3版)> 笔记主要为<JavaScript高级程序设计(第3版)>读书记录,按照此书的章节学习记录.方便以后查询复习(PS:正版书99大洋,没舍得买.在淘宝46买了一本盗版的并带一本 <JavaScript DOM编程艺术(第2版)>).两本书同时阅读,但以<JavaScript高级程序设计(第3版)>为主要学习路线.重要说明性内容将以近似书中原文摘出(以免出现个人解释歧义),外加自己遇到特殊情况说明(不

第三章: Expressions and Flow Control

第三章: Expressions and Flow Control一:局部变量和实例变量定义变量是指设定变量的数据类型和变量的名字,Java语言要求变量遵循先定义,再初始化,然后使用的规则.作用域:指它的存在范围,只有在这个范围内,程序代码才能访问它.变量的生命周期是指从一个变量被创建并分配内存空间开始, 到这个变量被销毁并清除其所占用内存空间的过程局部变量(参数变量也可以看成是局部变量): 1)位置:定义在方法中或者在方法中的{} 2)使用:先赋值后使用 3)作用域:定义的方法中或者定义的{}