0.1+0.2 !== 0.3?

作者&投稿:尉绿 (若有异议请与网页底部的电邮联系)
~ https://cloud.tencent.com/developer/article/1661734?from=article.detail.1748861
先说结论:十进制转二进制然后转十进制计算导致的精度丢失,原因就是二进制表示某些浮点数小数是除不尽的。

JS使用的IEEE-754标准,使用双精度浮点数,这种格式以 64 位存储数字,其中数字(分数)存储在位 0 到 51 中,指数存储在位 52 到 62 中,符号存储在位 63 中。

我们使用乘2取整法将0.1转为二进制:
0.1 * 2 = 0.2 => 0
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
0.6 * 2 = 1.2 => 1
0.2 * 2 = 0.4 => 0
......
0.000110011001100110011001100110011001100110011001100110011...... (0011无限循环)
科学计数法(左移四位):1.10011001100110011001100110011001100110011.... * 2^(-4)
尾数:10011001100110011001100110011001100110011.......
指数:2^11 - 1 = 1023 1023 + (-4) = 1019 1019 => 1111111011 in base2
我们可以看出这是无限循环数,但是IEEE-754标准只能存储52位尾数,所以此时就产生精度丢失。

同理我们可以得出0.2的二进制科学计数法为:
1.10011001100110011001100110011001100110011...... * 2^(-3)
尾数:10011001100110011001100110011001100110011.......
指数:2^11 - 1 = 1023 1023 + (-3) = 1020 1020 => 1111111100 in base2

对阶的目的是使两数的小数点位置对齐,方便两数进行运算,换句话说就是两数的阶码要相等。根据小阶向大阶看齐的原则,应使0.1的尾数向右移动1位(可以理解为小数点向左移动1位),阶码加1。
尾数向右移动1位后,阶码和尾数的值变化如下:
阶码:01111111011 + 1 ——> 01111111100
尾数:11001100110011001100110011001100110011001100110011010
=> 1100110011001100110011001100110011001100110011001101

转换IEEE-754存储表示分别为:
0 01111111100 1100110011001100110011001100110011001100110011001100
0 01111111100 1001100110011001100110011001100110011001100110011001

尾数部分M通常都是规格化表示的,非"0"的尾数其第1位总是"1",而这一位也称作隐藏位,因为存储的时候该位会被省略。比如存储1.0110时,只存储尾数0110,等到读取的时候才把第1位的1加补上去,这么做相当于多保存了1位有效数字。
0.1的尾数 + 0.2的尾数 =
0.1100110011001100110011001100110011001100110011001101 + 1.1001100110011001100110011001100110011001100110011010 = 10.0110011001100110011001100110011001100110011001100111
由此可得:0.1 + 0.2 = 10.0110011001100110011001100110011001100110011001100111 * 2^(-3)

根据尾数求和的结果,进行规格化处理,即尾数向右移1位,阶码加1。
1.00110011001100110011001100110011001100110011001100111 * 2^(-2)
尾数只能存储52位,红色的“1”需要舍去,根据进1舍0的原则进行操作可得:
1.0011001100110011001100110011001100110011001100110100 * 2^(-2)

存储格式:0 01111111101 0011001100110011001100110011001100110011001100110100

转十进制:
规格值转为非规格值(依照指数右移两位)
1.0011001100110011001100110011001100110011001100110100 * 2^(-2) => 0.010011001100110011001100110011001100110011001100110100
= 0.30000000000000004


全州县18223446875: 0.1,0.1,0.2,0.3,0.5找规律 -
恭弯经乐: 0.1+0.1=0.2 就是下一个数字 然后0.2+0.1=0.3 然后0.3+0.2=0.5 这个规律就行成了 我想就是这样

全州县18223446875: 找规律填空:0.1,0.2,0.3,0.5,0.8,______,2.1. -
恭弯经乐:[答案] 因为0.1+0.2=0.3, 0.2+0.3=0.5, 0.3+0.5=0.8, 所以0.5+0.8=1.3, 验证:0.8+1.3=2.1, 故答案为:1.3.

全州县18223446875: 0.1加0.2等于几
恭弯经乐: 等于0.3.这是最标准的答案

全州县18223446875: 0.1+0.2=0.3? -
恭弯经乐: 0.1+0.2 运算中的结果不是0.3 ,而是0.30000000000000004.所以false;所以结果为0.2;这个是js自身的问题.js自身的加减乘除都存在问题.所以如果想确保万无一失,最好自己写方法实现运算.

全州县18223446875: 20%+10%为什么等于0.12? -
恭弯经乐: 当你将两个百分数相加时,它们表示的是相对于总数的百分比.因此,如果你想计算 20% + 10%,则实际上是在计算 0.2 + 0.1.因此,20% + 10% 等于 0.2 + 0.1,即 0.3.但是,如果你使用了小数来表示百分数,则结果会有所不同.例如,如果你使用 0.2 表示 20%,那么 0.2 + 0.1 就等于 0.3,即 30%.因此,当你使用小数来表示百分数时,将两个小数相加的结果并不一定等于这两个百分数的总和.希望我的回答能帮到你!

全州县18223446875: 手机计算器10%+20%为什么等于0.12? -
恭弯经乐: 那就是算错了,10%等于0.1,20%等于0.2,所以计算结果应该等于0.3

全州县18223446875: 0.1 0.1 0.2 0.3 0.5 0.8( ) ( ) 2.1 4.1 -
恭弯经乐: 0.1+0.1=0.20.1+0.2=0.30.2+0.3=0.50.3+0.5=0.80.5+0.8=1.31.3+0.8=2.12*1+0.1=2.12*2+0.1=4.12*3+0.1=6.12*4+0.1=8.1......2*n+0.1=2n+0.1

全州县18223446875: 小数这一节该怎么讲(小学数学) -
恭弯经乐: 小数是分式数一种,0.1+0.2=0.3 0.3—0.1=0.2

全州县18223446875: 0.1+0.2+0.3+......+9.8+9.9等于多少 -
恭弯经乐: 解:原始等于(0.1+9.9)+(0.2+9.8)+……+(4.9+5.1)+5.0 =10+10+……10+5 =490+5 =495 这是个等差数列,求和公式是 (首项+末项)*项数/2=和 扩展资料等差数列是常见数列的一种,如果一个数列从第二项起,每一项与它的前一项的差...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网