js--数字精度与范围、位运算、逻辑运算

IEEE754的存储格式--64bit

  • 求值方法:(-1)S*(1.M)*2(E-1023)
  • 64位,1位总的符号位S,11位阶码E(移码),53位尾数位M(原码),其中1位隐藏。
  • 阶码用移码表示,主要控制小数点在尾数部分的跳转,11位阶码中,又有1位表示符号位,10位来表是数字,按无符号数来计算,原本可以表示02047的数据,但除去阶码为全0、全1的情况,剩下可以表示12046种情况,移码偏置是+1023,所以所有从数位上换算出来的数字,都要 减去 1023,得到的才是阶码的真实值。真实值的范围是:-1022~1023。所以指数范围为2^-1022 ~ 2^1023。
    -尾数部分默认规格化后是1.xxx,1省略不写,主要控制小数部分的精确数字,是表示数字的主要部分。位数部分分为规格化和非规格化,范围比较复杂,下面再进行讨论。
  • 表示0时,所有位数全为0
  • 表示无穷大时,阶码全为1,尾数全为0,符号位指示是正无穷还是负无穷。

数值范围

浮点数

  • 最小正浮点数: Number.MIN_VALUE = 5e-324。

  • 解析: 这个值等价于(Math.pow(2,-52) ) * Math.pow(2,-1022) = Math.pow(2,-1074)。

    • 首先取阶码为最小值Math.pow(2,-1022),这里不用多说。
    • 然后是取尾数为最小值,按照IEEE754的标准,尾数部分规格化以后隐含还有1位,最小值是1.0000....0001(小数后第52位为1,其他为0),此时的最小值是1+Math.pow(2, -52)。但是其实IEEE754还有另外一条规则,规定当浮点数的指数为允许的最小指数值,尾数不必是规范化的。当作为非规格化数据时,尾数部分所能表达的最小值是Math.pow(2, -52)。因此这里所取的最小正尾数就是非规格化的数据。
    • 所以最后得到的最小正浮点数就是Math.pow(2,-1074);
    • 补充:为了保存非规范浮点数,IEEE 标准采用了类似处理特殊值零时所采用的办法,即用特殊的指数域值 emin - 1 加以标记,而一般来说,阶码移码的偏置值都是emin+1,此时进行了emin-1+(emin+1)以后,阶码的值全为0,此时如果尾数为0且符号位也为0,则表示的值就是0;如果尾数不为0,表示的就是非规格化的数据。
      • 例: 想要表示0.0001 × 2^-125,表达为规范浮点数则为 1.0 × 2-129。问题在于其指数大于允许的最小指数值,所以无法保存为规范浮点数。此时可以保存为非规格化数据,先将阶码化为能表示的最小值,0.001 * 2 ^ -126,阶码经过-1处理为:-126 -1 +127 = 0。 尾数部分小数点左边的0要像规格化中的1一样省略,所以这个数据最终表示为(32bit形式):0(符号位) 0000 0000(阶码) 0010 000000.....(剩余尾数部分全为0) = 0010 0000 (十六进制)
  • 最大正浮点数: Number.MAX_VALUE = 1.7976931348623157e+308 。

  • 解析:等价于 (Math.pow(2,53) - 1) * Math.pow(2,971)

  • 首先看尾数部分,表示为最大值时是1.1111...111(小数点右边52个1),在不考虑小数点带来的影响时,53个1的数据表示为(Math.pow(2,53) - 1)

  • 然后看阶码部分,阶码所能表示的最大值是1023,但是为了让前面的尾数部分的小数点跳到有效值的最后,要让1023-52 = 971.所以阶码部分最大值为Math.pow(2,971)

  • 所以最终的最大值为:(Math.pow(2,53) - 1) * Math.pow(2,971)

连续整数

  • 最大正整数(连续且精确):Math.pow(2, 53) =9007199254740992

  • 解析:这里之所以没有减一,是因为这是浮点数,可以用阶码来控制小数点的跳转。

  • 如果是Math.pow(2, 53) - 1,其表示为:

    • 尾数部分为53个1,所表示的值是1.11111....1( 小数点后52个1 )
    • 阶码部分要表示的值是52,加上偏置1023,结果是1075,表示为二进制是:100 0011 0011。
    • 所以最终这个值表示为 0 | 100 0011 0011 | 111111...111(52个1)
  • 如果是Math.pow(2, 53),其表示为:

    • 尾数部分为1.000...000(小数点后52个0)
    • 阶码部分要移53位,加上偏置值1023,结果是1076,表示为二进制是:100 0011 0100.
    • 所以最终这个值表示为 0 | 100 0011 0100 | 0000...000(52个0,小数点左边的1被默认省略)
  • 因此,Math.pow(2, 53) 也是可以准确表示出来的,但如果大于Math.pow(2, 53) ,由于尾数部分不够位数来精确地指定某个值,就会发生四舍五入的情况,带来精度误差。

  • 最小负整数(连续且精确):Math.pow(2,-53) = -9007199254740992

  • 解析:表示方法就是Math.pow(2,-53)的符号位为1。

    • 1 100 0011 0100 0000...000(52个0,小数点左边的1被默认省略)
但是还要注意,虽然我们确定Math.pow(2,-53) 和Math.pow(2,53) 都可以准确表示出来,但是在JS中的安全数还是要在这个基础上 减1
 Number.MAX_SAFE_INTEGER = 9007199254740991
 Number.MIN_SAFE_INTEGER = -9007199254740991

补充:

  • 对于位运算,js仅支持32位整数,其中1位符号位,31位数字位。

  • 32bit最大正整数:Math.pow(2, 31) - 1 =2147483647

  • 32bit最小负整数:Math.pow(2, 31) = -2147483648

  • 【个人觉得当做32位处理时,用的应该是补码】

  • 位运算:

  • ~ 按位非(NOT)

    • 包括符号位在内,按位取反。本质是:在原操作数上添加负号,再减1
  • & 按位与(AND)

    • 包括符号位,用与逻辑运算。
  • | 按位或(OR)

    • 包括符号位,用或逻辑运算。
  • ^ 按位异或(XOR)

    • 包括符号位,相异为1,相同为0.
  • << 左移

    • 左移不改变符号位,右边空缺补0.
    • 本质是原数乘以2的移位数次方。
  • . >> 右移

    • 不改变符号位,即用符号位来填补左边出现的空缺。
    • 本质是原数除以2的移位数次方。
  • . >>> 无符号右移

    • 不论正负,左边出现的空缺都用0来填补。
  • || 或运算

    • 逻辑运算过后如果为true,取第一个为true的值,如果为false,取最后一个为false的值
    • 短路规则:var a = “” || null || 3 || 4 —-> var a = fasel || false || true || true 结果为true 则返回第一个true,即是3
  • && 与运算

    • 逻辑运算过后如果为true,取最后一个为true的值,如果为false,取第一个为false的值
    • 短路规则:var b = 4 && 5 && null && 0 ——> var b = true && true && false && false 结果是false 则返回第一个false 即是null .
  • 如果某次计算结果得到了一个超出javascript数值范围的值,这个值会自动转化成Infinity。(Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY)

  • 想要确定一个值是不是有穷的,可以使用 isFinite( num ) 函数。

  • 想要确定一个值是不是NaN,可以使用isNaN( num )函数,但这里并不是只有NaN才会使得该函数返回true,任何对象以及非纯数字类型的字符串,都会使该函数返回true,真正判断一个数据是否是NaN的,是用 a==a来判断。如果是NaN,则返回false.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容