为什么0.1+0.2=0.30000000000000004

浮点数运算

你使用的语言并不烂,它能够做浮点数运算。计算机天生只能存储整数,因此它需要某种方法来表示小数。这种表示方式会带来某种程度的误差。这就是为什么往往 0.1 + 0.2 不等于 0.3。

为什么会这样?

实际上很简单。对于十进制数值系统(就是我们现实中使用的),它只能表示以进制数的质因子为分母的分数。10 的质因子有 2 和 5。因此 1/2、1/4、1/5、1/8和 1/10 都可以精确表示,因为这些分母只使用了10的质因子。相反,1/3、1/6 和 1/7 都是循环小数,因为它们的分母使用了质因子 3 或者 7。二进制下(进制数为2),只有一个质因子,即2。因此你只能精确表示分母质因子是2的分数。二进制中,1/2、1/4 和 1/8 都可以被精确表示。但是,1/5 或者 1/10 就变成了循环小数。所以,在十进制中能够精确表示的 0.1 与 0.2(1/10 与 1/5),到了计算机所使用的二进制数值系统中,就变成了循环小数。当你对这些循环小数进行数学运算时,并将二进制数据转换成人类可读的十进制数据时,会对小数尾部进行截断处理。

下面是在不同的语言中,运行 0 .1 + 0.2 的输出结果:


语言


代码


结果


C


#include<stdio.h>int  main(int argc, char* argv) {printf(“%.17fn”, .1+.2);return 0;}


0.30000000000000004


C++


#include  <iomanip>std::cout << setprecision(17) << 0.1 + 0.2  << std.endl;


0.30000000000000004


PHP


echo .1 + .2;


0.3


注1:PHP 将  0.30000000000000004 格式化成字符串时,会把它缩短成 “0.3″。为了得到需要的浮点数结果,在 ini文件中调整精度设置:iniset(“precision”,  17)。


MySQL


SELECT .1 +  .2;


0.3


Postgres


SELECT select  0.1::float + 0.2::float;


0.3


Delphi XE5


writeln(0.1 +  0.2);


3.00000000000000E-0001


Erlang


io:format(“~w~n”,  [0.1 + 0.2]).


0.30000000000000004


Elixir


IO.puts(0.1 +  0.2)


0.30000000000000004


Ruby


puts 0.1 + 0.2  And puts 1/10r +  2/10r


0.30000000000000004  And 3/10


注2:Ruby 2.1及以后版本在语法上支持有理数。对于老版本,请使用 Rational。Ruby还有一个专门处理小数的库: BigDecimal


Python 2


print(.1 + .2)

float(decimal.Decimal(“.1″)  + decimal.Decimal(“.2″))  .1 + .2


0.3

0.3

0.30000000000000004


注3:Python 2 中的 “print” 语句将 0.30000000000000004 转成一个字符串,并缩短成 “0.3″。为了达到需要的浮点数结果,使用 print(repr(.1 + .2))。在 Python 3中这是内置设定(见下面例子)。


Python 3


print(.1 + .2)

.1 + .2


0.30000000000000004

0.30000000000000004


Lua


print(.1 + .2)  print(string.format(“%0.17f”, 0.1 + 0.2))


0.3  0.30000000000000004


JavaScript


document.writeln(.1  + .2);


0.30000000000000004


Java


System.out.println(.1  + .2);System.out.println(.1F + .2F);


0.30000000000000004

0.3


Julia


.1 + .2


0.30000000000000004


注4:Julia 内置 支持有理数 ,并且还有一个内置的数据类型BigFloat,它支持任意精度。要得到正确的运算结果,使用 1//10 + 2//10 会返回3//10。


Clojure


(+ 0.1 0.2)


0.30000000000000004


注5:Clojure 支持任意精度的数据。 (+ 0.1M 0.2M) 返回 0.3M,而 (+ 1/10 2/10) 返回 3/10。


C#


Console.WriteLine(“{0:R}”,  .1 + .2);


0.30000000000000004


GHC (Haskell)


0.1 + 0.2


0.30000000000000004


注6:Haskell 支持有理数。要得到正确的运算结果,使用 (1 % 10) + (2 %  10) 返回 3 % 10。


Hugs (Haskell)


0.1 + 0.2


0.3


bc


0.1 + 0.2


0.3


Nim


echo(0.1 +  0.2)


0.3


Gforth


0.1e 0.2e f+  f.


0.3


dc


0.1 0.2 + p


.3


Racket (PLT  Scheme)


(+ .1 .2) And  (+ 1/10 2/10)


0.30000000000000004  And 3/10


Rust


extern crate  num; use num::rational::Ratio; fn main() { println!(.1+.2); println!(“1/10 +  2/10 = {}”, Ratio::new(1, 10) + Ratio::new(2, 10)); }


0.30000000000000004  3/10


注7:Rust 中,使用 num  crate 支持获得 有理数支持 。


Emacs Lisp


(+ .1 .2)


0.30000000000000004


Turbo Pascal  7.0


writeln(0.1 +  0.2);


3.0000000000E-01


Common Lisp


(+ .1 .2) And  * (+ 1/10 2/10)


0.3 And 3/10


Go


package main  import “fmt” func main() { fmt.Println(.1 + .2) var a float64 = .1 var b  float64 = .2 fmt.Println(a + b) fmt.Printf(“%.54fn”, .1 + .2) }


0.3  0.30000000000000004 0.299999999999999988897769753748434595763683319091796875


注8:Go语言的数字常数有任意精度


Objective-C


0.1 + 0.2;


0.300000012


OCaml


0.1 +. 0.2;;


float =  0.300000000000000044


Powershell


PS C:>0.1 +  0.2


0.3


Prolog  (SWI-Prolog)


?- X is 0.1 +  0.2.


X =  0.30000000000000004.


Perl 5


perl -E ‘say  0.1+0.2′ perl -e ‘printf q{%.17f}, 0.1+0.2′


0.3  0.30000000000000004


Perl 6


perl6 -e ‘say  0.1+0.2′ perl6 -e ‘say sprintf(q{%.17f}, 0.1+0.2)’ perl6 -e ‘say 1/10+2/10′


0.3 0.30000000000000000  0.3


注9:Perl 6 与 Perl 5 不同,默认使用有理数。因此 .1 被存储成类似这样 { 分子 => 1, 分母 => 10 }.


R


print(.1+.2)  print(.1+.2, digits=18)


0.3  0.300000000000000044


scala


scala -e  ‘println(0.1 + 0.2)’ And scala -e ‘println(0.1F + 0.2F)’ And scala -e  ‘println(BigDecimal(“0.1″) + BigDecimal(“0.2″))’


0.30000000000000004  And 0.3 And 0.3


Smalltalk


0.1 + 0.2.


0.30000000000000004


Swift


0.1 + 0.2


0.3


D


import  std.stdio; void main(string[] args) { writefln(“%.17f”, .1+.2);  writefln(“%.17f”, .1f+.2f); writefln(“%.17f”, .1L+.2L); }


0.29999999999999999  0.30000001192092896 0.30000000000000000

时间: 2024-11-06 13:26:09

为什么0.1+0.2=0.30000000000000004的相关文章

如何解决JavaScript中0.1+0.2不等于0.3

console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!==0.3,这是为什么呢?这个问题也会偶尔被用来当做面试题来考查面试者对 JavaScript的数值的理解程度. 在JavaScript中的二进制的浮点数0.1和0.2并不是十分精确,在他们相加的结果并非正好等于0.3,而是一个比较接近的数字 0.30000000000000004 ,所以条件判断结果

为什么在JavaScript中0.1+0.2不等于0.3?

0.1+0.2不等于0.3?是不是有点颠覆你的认知,但是,在js中,是真实存在的! console.log(0.1+0.2); // 0.30000000000000004 其实这都是因为浮点数运算的精度问题. 简单来说,因为计算机只认识二进制,在进行运算时,需要将其他进制的数值转换成二进制,然后再进行计算. 由于浮点数用二进制表达时是无穷的: // 将0.1转换成二进制 console.log(0.1.toString(2)); // 0.000110011001100110011001100

为什么计算机编程语言中:0.1+0.2不等于0.3

最近在学习JS过程中发现在计算机JS时发现了一个非常有意思事,0.1+0.2的结果不是0.3,而是0.30000000000000004,但先将小数做乘法然后相加,再除回来就得到想要的0.3 我用python试了一下,发现python也是一样的,结果也是0.30000000000000004. 然后我开始信息搜集,最后找到了答案.想知道这其中的原因,要先理解这些点:二进制.指数形式.IEEE 754标准. 1.二进制 在计算机中所有的数据都是二进制形式存储的,包括整数.浮点数以及其他所有类型的数

Angular 1.0演变Angular 2.0的简单优势列举

首先,Angular最核心的4大特性分别是: 1.模块化 2.MVC 3.双向数据绑定 4.指令 Angular 1.0演变Angular 2.0的简单优势列举: 1.性能限制上的优化 说明:随着时间的推移,各种特性被加入进去以适应不同场景下的应用开发,在最初的架构受到了限制,而Angular 2.0很好的解决了这些问题. 2.仿照WEB后端的结构模式来编写前端 说明:支持模块.类.lambda表达式. generator等新的特性 3.支持移动端开发 说明:Angular1.x没有针对移动 应

c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结【转载】

引用:http://blog.csdn.net/attilax/article/details/42014327 c# .net 3.5 4.0 各个版本新特性战略规划总结 1. --------------.Net Framework版本同CLR版本的关系1 2. paip.------------SDK2.0功能-------------2 2.1. 泛型:2 3. --------------sdk3.0  增加了以下功能..2 3.1. LINQ 3 4.  ----------sdk4

React v15.5.0更新说明 &amp; v16.0.0更新预告

React今日发布了15.5.0版本,同时这也将是以15开头的最后一个版本,下一次发布,我们将迎来React 16.0.0 在15.5.0这一版本中,主要有以下两处改动: 独立React.PropTypes 在之前的版本之中,我们可以通过React.PropTypes这个API访问React内置的一些类型来检查props,在15.5.0版本中,这一API被独立成了一个新的包 prop-types // 15.4 以前 import React from 'react'; class Compon

System.Web.Mvc 3.0.0.1 和 3.0.0.0 有什么区别?被 Microsoft ASP.NET MVC 的一次安全更新害惨了!!!

今天更新站点时,发现网站竟然报错 ... uses 'System.Web.Mvc, Version=3.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 最终发现

csharp:using Newtonsoft.Json.Net2.0 in .net 2.0 webform

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

安装HBase 0.94.6-cdh4.3.0

安装HBase 0.94.6-cdh4.3.0 设定HBase的配置文件,由于安装的是cdh版,各版本直接匹配,互相依赖的jar包也都正确,只需要配置下hbase的环境变量和配置文件即可. 1.配置hbase-env.sh,添加JAVA_HOME环境变量 [html] view plaincopy export JAVA_HOME=/usr/java/default/  其他暂时不用添加 export HBASE_MANAGES_ZK=true 2.修改hbase-site.xml,如下配置 [

ASP.NET Thread Usage on IIS 7.5, IIS 7.0, and IIS 6.0

I’d like to briefly explain how ASP.NET uses threads when hosted on IIS 7.5, IIS 7.0 and IIS 6.0, as well as the configuration changes that you can make to alter the defaults. Please take a quick look at the “Threading Explained” section in Chapter 6