计算机中0.1+0.2等于多少?0.3还是0.30000000000000004?

最后编辑于 2019年05月25日 开发

计算机中的浮点数(Floating Point),特别是小数,非常有意思。我们都知道小数分为有限小数和无限小数,而小数也可以用分数表示,并且根据分母的质因子,就可以区分这个分数是否可以化成有限小数和无限小数。

Prime factor(质因子,也叫质因数)是指能整除一个正整数的质数,换句话说,每个正整数都能唯一表示为它的质因数的乘积。只有一个质因子的正整数叫做质数,数字1没有质因子。

对于十进制来说,10的质因子是2和5。因此,如果一个最简分数中分母的质因子只有2和5,这个分数就可以化成有限小数;如果分母中含有2和5以外的质因子,这个分数就不能化成有限小数。

对于二进制来说,2的质因子是2。因此,如果一个最简分数中分母的质因子只有2,这个分数就可以化成有限小数;如果分母中含有2以外的质因子,这个分数就不能化成有限小数。

在十进制的数学里,1/10=1/(2x5)表示0.1,分母中的质因子是2和5;1/5表示0.2,分母中的质因子是5。0.10.1+0.2很显然等于0.3。但是在计算机的二进制里,1/10和1/5都不能化成有限小数。也就是说计算机里的浮点数0.1和0.2,实际上并不是有限小数,它们后面还有一个小尾巴。

在大部分情况下,计算机里的0.1和0.2等于0.30000000000000004。

一位叫做Erik Wiffin的程序员,就汇总了在不同的编程语言下0.1+0.2的输出结果,并放在了他的网站上。下面选了几个常见的编程语言下的输出情况:

Python 3:   
print(.1 + .2)
.1 + .2
float(decimal.Decimal('.1') + decimal.Decimal('.2'))
float(fractions.Fraction('0.1') + fractions.Fraction('0.2'))
0.30000000000000004
0.30000000000000004
0.3
0.3

Java:   
System.out.println(.1 + .2);
System.out.println(.1F + .2F);
0.30000000000000004
0.3

JavaScript: 
console.log(.1 + .2);
0.30000000000000004

PHP:
echo .1 + .2; 
var_dump(.1 + .2);
0.3 float(0.30000000000000004441)

C:  
#include<stdio.h>
int main(int argc, char** argv) {
    printf("%.17f\n", .1+.2);
    return 0;
}
0.30000000000000004

C++:    
#include <iomanip>
std::cout << std::setprecision(17) << 0.1 + 0.2
0.30000000000000004

C#: 
Console.WriteLine("{0:R}", .1 + .2);
Console.WriteLine("{0:R}", .1m + .2m);
0.30000000000000004
0.3

Objective-C:    
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSLog(@"%.17f\n", .1+.2);
  }
  return 0;
}
0.30000000000000004

Swift:  
0.1 + 0.2
NSString(format: "%.17f", 0.1 + 0.2)
0.3
0.30000000000000004

Ruby:   
puts 0.1 + 0.2
puts 1/10r + 2/10r
0.30000000000000004
3/10

Erik Wiffin的网站:
http://0.30000000000000004.com

登录注册后才能评论。