·  阅读 3857

# 因吹斯挺

console.log(0.1+0.2===0.3) // false
console.log(1.1+0.2===1.3) // true

# 十进制转二进制

## 整数部分

6 / 2 = 3...0  => 0
3 / 2 = 1...1  => 1
1 / 2 = 0...1  => 1

6 => 110

## 小数部分

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 => 00.1 => 000110011001100110011001100110011001100110011001100110011...

110.00011001100110011001100110011001100110011001100110011

1.1000011001100110011001100110011001100110011001100110011×2^(2)

# 浮点数在计算机中如何存储

sign: 0
exponent: 2 + 1023 => 10000000001
fraction: 1000011001 1001100110 0110011001 1001100110 0110011001 10 011 (只能保留52位，多余部分向偶舍入)
=> 1000011001 1001100110 0110011001 1001100110 0110011001 10

# 浮点数加法

0.1 => 0 01111111011[1]1001100110011001100110011001100110011001100110011010
+
0.2 => 0 01111111100[1]1001100110011001100110011001100110011001100110011010

1. 对齐指数，小的往大的对齐。所以 0.1 指数部分加一，小数点需要往左移一位，超出部分向偶舍入
0.1 => 0 01111111100[0]1100110011001100110011001100110011001100110011001101 0
0.1 => 0 01111111100[0]1100110011001100110011001100110011001100110011001101

2. 小数部分相加
0.1 => 0 01111111100[0]1100110011001100110011001100110011001100110011001101
+
0.2 => 0 01111111100[1]1001100110011001100110011001100110011001100110011010
Res =>             [10]0110011001100110011001100110011001100110011001100111

3. 小数部分相加的结果超出了52位，小数点要左移一位，多余部分要向偶舍入
Res => 0 01111111101[1]0011001100110011001100110011001100110011001100110011 1
Res => 0 01111111101[1]0011001100110011001100110011001100110011001100110100

4. 推导 0.3 的表示
0.3 => 0 01111111101[1]0011001100110011001100110011001100110011001100110011

1.1 => 0 01111111111[1]0001100110011001100110011001100110011001100110011010
+
0.2 => 0 01111111100[1]1001100110011001100110011001100110011001100110011010

1. 对齐指数，小的往大的对齐。所以 0.2 指数部分加三，小数点需要往左移三位，超出部分向偶舍入
0.2 => 0 01111111111[0]0011001100110011001100110011001100110011001100110011 010
0.2 => 0 01111111111[0]0011001100110011001100110011001100110011001100110011

2. 小数部分相加
1.1 => 0 01111111111[1]0001100110011001100110011001100110011001100110011010
+
0.2 => 0 01111111111[0]0011001100110011001100110011001100110011001100110011
Res => 0 01111111111[1]0100110011001100110011001100110011001100110011001101

3. 推导 1.3 的表示
1.3 => 0 01111111111[1]0100110011001100110011001100110011001100110011001101

# 问题

0 01111111011[1]0000000000000000000000000000000000000000000000000000
+
0 01111111100[1]0000000000000000000000000000000000000000000000000000

=>

0 01111111100[0]1000000000000000000000000000000000000000000000000000 0
+
0 01111111100[1]0000000000000000000000000000000000000000000000000000

=>

0 01111111100[0]1000000000000000000000000000000000000000000000000000
+
0 01111111100[1]0000000000000000000000000000000000000000000000000000
=
0 01111111100[1]1000000000000000000000000000000000000000000000000000

0.0625+0.125

# 附录

#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
double data;
unsigned long long int buff;
int i;
char s[66];
data = (double)0.1;
memcpy(&buff, &data, 8);
for(i = 65; i >=0; i--) {
if (i == 1 || i == 13) {
s[i] = '-';
} else {
if(buff%2 == 1){
s[i] = '1';
} else {
s[i] = '0';
}
buff /= 2;
}
}

printf("%s\n", s);
}