java中double二进制浮点计算问题

使用的Eclipse软件:
double a = 0.1+0.2;
double b = 0.3;
输出结果:a!=b;
double c = 0.2+0.2;
double d =0.4;
输出结果 a=b;
我手算二进制发现a和b,c和d的二进制都相同,为什么结果不同,求科普。

4个回答

0.1 0.2 0.3 0.4 在2进制中都是无限循环小数。它们都不能精确表示(只有0.5 0.25 0.125 ... 以及它们的组合,比如 0.75 0.3125 ...可以表示为有限小数)
它们进行四则运算的结果,就是近似值,而且会有不同的舍入误差。
所以最后结果不同很正常。
“手算二进制”没用,你怎么舍入的,计算机不一定按照你的方式(好比2/3是0.66666还是0.66667就不好说了)

特别是,底层硬件不同,计算精度都不同。比如说,x87的浮点运算,虽然也是64bit的精度,但是内部的寄存器是80bit的,而sse就达不到这个精度,而gpu的fp64,精度就更差了。而jvm用的什么底层硬件指令,这个就无法由你控制了。

结论就是,不要试图用相等和不等比较浮点数,而是用差的绝对值<epslon的方式比较。

c里面算俩浮点数是否相等,都是相减后的绝对值是否小于一个很小的值:
abs(a-b)<0.00001
不知java里面是怎么算的

图片说明

图片说明

可参考这篇博客修改为对应java的语法
https://blog.csdn.net/u013347241/article/details/79210840

caozhy Ds Rxr 2018.08.08 12:22
已采纳
0.1 0.2 0.3 0.4 在2进制中都是无限循环小数。它们都不能精确表示(只有0.5 0.25 0.125 ... 以及它们的组合,比如 0.75 0.3125 ...可以表示为有限小数)
它们进行四则运算的结果,就是近似值,而且会有不同的舍入误差。
所以最后结果不同很正常。
“手算二进制”没用,你怎么舍入的,计算机不一定按照你的方式(好比2/3是0.66666还是0.66667就不好说了)

特别是,底层硬件不同,计算精度都不同。比如说,x87的浮点运算,虽然也是64bit的精度,但是内部的寄存器是80bit的,而sse就达不到这个精度,而gpu的fp64,精度就更差了。而jvm用的什么底层硬件指令,这个就无法由你控制了。

结论就是,不要试图用相等和不等比较浮点数,而是用差的绝对值<epslon的方式比较。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
java浮点计算
浮点计算
浮点,内存,二进制,十进制浮点转二进制
进行一下格式说明(011)2 括号里面表示某个数的二进制表示法,后面的2表示二进制,我们先在此做区分,内存 的存储和其大端小端有关,也就是以后网络编程中会用到的,不过一般都是大端,即高位在后。 还有后面的默认数值位默认前置一个 1 即 00000 做解析时是 100000 高位在后在做偏移运算的时候效率比较高。   1.75 = 0 01111111 110000000000000...
java中double计算精度问题
最近在工作中碰到一个关于double精度的问题,记录下。 首先见如下代码,最终的计算结果是不相等的,因为最终invoiceItemMoneyAmount的值变成了168.82000000000002 double money= 168.82; List itemMoneyList = Lists.newArrayList(); itemMoneyList.add("23.80"); itemM
double 浮点数据精确度
[code=&quot;java&quot;] /* * * * * 版权所有,并保留所有权利。 * */ package com.legendshop.util; import java.math.BigDecimal; /** * * * * 官方网站: * */ public class Arith { // 默认除法运算精...
java的double计算精度问题
[img=https://img-bbs.csdn.net/upload/201505/16/1431759651_741565.png][/img]rnrn[img=https://img-bbs.csdn.net/upload/201505/16/1431760713_806782.png][/img]rnrn如图,我开始以为是用的eclipse的问题,所以用命令提示符运行,结果还是一样rnrn想问一下,为什么会得到这个结果
Java计算double精度问题
分析: 我们在一些计算的时候,特别是金融项目,double类型的数据,经常会有精度丢。 例如: System.out.println(0.09 + 0.01); System.out.println(1 - 0.32); System.out.println(1.015 * 100); System.out.println(1
关于浮点计算的问题
var a = Math.Floor(0.58 * 100);rnrna 的结果是多少?rnrn欢迎讨论.rn
AM3354 浮点计算问题
小弟遇到一个问题,请大神指点一二:rn软件硬件平台:WinCE6.0 + AM3354。rn由于WinCE6.0编译器不支持浮点指令,小弟使用了ARM官方提供的VFP库。该库之前在WinCE6.0+S3C6410上使用,没有问题。rn但是在当前的平台上,会出现如下问题:rn机器在上电后,启动我们的数控软件,数控软件中有比较多的浮点运算。浮点运算的过程会出现偏差,比如:rn正确的计算结果为:rn540.63510936875002 :::0x4080E514B4388151rn出现问题时结果为:rn540.63510936874991 :::0x4080E514B4388150rnrn正确的计算结果为:rn2554.9807209000001:::0x40A3F5F6210CC002rn错误的计算结果为:rn2554.9807208999996:::0x40A3F5F6210CC001rnrn计算数据都是类似的,就不一一举例了。通过数据比较,看出,其二进制浮点标示,最低位差了1。rn正确结果比错误的差别就是最后一位的值。rn小弟推测,可能是round规则的问题,但是找不到证据。请大神们指点一二。感激不尽。rnS3C6410的硬件浮点处理单元为VFPv2,AM3354为VFPv3+NEON。rnrn
浮点计算的奇怪问题
double lng = 11417.9006; rnlng = lng + 0.0001;rnrn为什么 结果有时候变成 11417.90060001 或者 11417.90069997 呢?
浮点计算
js浮点计算 方法一: 指定要保留的小数位数 (0.1+0.2).toFixed(1) = 0.3; 这个方法toFixed是进行四舍五入的也不是很精准,对于计算金额这种严谨的问题,不推荐使用,而且不通浏览器对toFixed的计算结果也存在差异。 方法二: 把需要计算的数字升级(乘以10的n次幂)成计算机能够精确识别的整数,等计算完毕再降级(除以10的n次幂),这是大部分编程语言处理精度差异的...
double计算,小数计算,BigDecimal计算,货币计算,float计算,浮点计算
背景: java中double、Double在小数计算时,比如金钱计算时,会出现“错误”的结果,必须使用BigDecimal计算,才能返回预期结果。 问题举例: System.out.println(0.06+0.01); //0.06999999999999999 解决方法: System.out.println(new BigDecimal("0.06").add(n
VB 浮点、二进制互换
vb 浮点数据 二进制转换 RCR16
浮点数值的二进制储存
转 float浮点数的二进制存储方式及转换 注,笔者有少量的笔误,但不影响阅读
IEEE中的浮点编码计算
float类型在内存中占4字节,最高位表示符号位,剩下31位,从右向左取8位用于表示指数,其余用于表示尾数 在进行二进制转化前,需要进行科学记数法转换,具体步骤如下 1.看符号位,正数为0,负数为1 2.将数转化为相应的二进制数 3.用科学记数法转化为相应的形式 如:1.xxxxxx*2^n() 4.n为指数,加上127 5..转化后用二进制拼接写出 举个例子
理解浮点类型float和double
c和c++对有效数位的要求是,float至少32位,double至少48位且不少于float,long double至少和double一样多(这里指的是二进制数)。通常来说,float为32位,double为64位,long double为80、96、128位。大多数情况下,编译器为float分配4字节,而为double则分配8字节。 float32位组成:最高位的1位为符号位,接着指数位共8位
double计算的问题...
double型计算时出现这种情况.rn结果是这样的:7.4948E7.rn是不是数太大了啊?rndouble类型不支持了啊?
Java 多线程与并发——Thread
Java 对操作系统提供的功能进行了封装,包括进程和线程,运行一个程序会产生一个进程,进程包含至少一个线程,每个进程对应一个 JVM 实例,多个线程共享 JVM 里的堆、方法区,每个线程拥有自己的虚拟机栈、本地方法栈、程序计数器,这 3 个区域随线程而生,随线程而灭。
Double 将浮点数值保留两位小数
Double db = new Double(324324.4255);  System.out.println(String.format(&quot;%.2f&quot;, db));
Swift的(Float)和(Double)浮点类型
Swift4.0入门视频教程,课程内容包含Swift入门知识、数据类型(元组、Dictionary、运算符)、流程控制、函数、类与对象、扩展协议、常见概念、实用进阶、案例实战。rn1、119节大容量课程:包含了Swift4.0语言大部分知识点;rn2、创新的教学模式:手把手教您iOS开发技术入门,一看就懂,一学就会;rn3、完美贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标;rn4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间;rn5、视频短小精悍:即方便于您的学习和记忆,也方便日后对功能的检索;
精确计算浮点(Double)类型数值
精确计算处理Java版Java版import java.math.BigDecimal;public class Demo1 { public static void main(String[] args) { //error错误 System.out.println(0.06+0.01); System.out.println(0.06-0.
关于java计算double型的问题
public class Test rn public static void main(String[] args)rn double d = 0.14;rn System.out.println(d*100);rn rnrnrn将会打印:14.000000000000002 (在我机器上是这样显示的)rnrn如果要是d=0.15,打印是15.0,这个是为什么呢?rn
double计算
在《剑指offer》里看到两个double不能直接使用 == 符号判断大小,有的资料也说double不能使用++。所以接下来这道单选题改怎么办呢?        在c语言中,要求运算必须是整型的运算符是: / ++ != %         不妨写个简单的程序测试一下,#include int main() { double a,b; a =
JAVA 中的浮点数据类型
讲下float类型、float类型是32位的,16位的尾数,16位的阶码如果使用a表示尾数,b表示阶码,则尾数和阶码就可以组成 a*2^b 范围的浮点数,下面是示例代码 long lg = 10L; //int x = lg; //WA: 编译错误 float f = lg; //AC: float的精度比long还高 System.out.println( f )
java中的浮点类型??
我刚刚从C++转过来,有一个问题想请教一下。rnrn在java中,为什么下面语句无法通过编译:rndouble d = 3.4;rnfloat f = (double)d;rn编译失败“cannot convert from double to float”。rn这是为什么呢?我已经使用“显式转换”了阿?(又如:long l = 33333333333l; short s = (short)l; 此处进行显式的“窄化转换”是可以成功的,为什么上面那个浮点类型转换不能成功呢?)rnrn又类似的:rnfloat f = (double)4.5;rn也是同样的失败理由。rnrn我不明白其中缘由,请高手执教,谢谢。
JAVA中的二进制问题!
在JAVA中,输入一个整数,如89,怎么样才能输出他的二进制以及十六进制..
计算分数的浮点数值
入门难度,计算分数的浮点数值
java中float和double的问题
        很多朋友都知道java中直接用float和double运算会有精度的问题,其本质的原因是计算机只认识二进制数,直接用二进制来表示带有小数的十进制,本来就是无法做到精确地,比如0.1转换成二进制位为: 0.1(十进制) = 0.0001100110011001100......(二进制)           所以在java中进行商业逻辑运算,还是要用BigDecimal,具体...
关于double在计算中的精度取舍问题
我想要做一个公式的计算的程序,其中有一个中间变量是double类型的,碰到这样的情况,实际手工计算的话正好应该是cos(90),结果是0,但是用程序计算出来的数字其实0.0007.。。。想请问一下,我应该怎么做才能确定将这一步的结果变成0,或者说我可以将这个double类型的数保留小数点后几位,之后再进行下面的计算,请告诉一下应该用什么函数,需要什么头文件,还有我用的是那种运行时出现命令行的控制台类型进行编程的,不是MFC,aof始终找不到应该用什么头文件。
java中double运算问题
java中的浮点数类型float和double进行运算时,并不能保证全部正确。比如:System.out.println(9.7*100);预想结果是970,实际确是:969.9999999999999解决方法用BigDecimal。...
浮点计算 高精度
大家都知道浮点运算。c语言里float有效位是5或6,现在编写一个浮点程序。比如就计算1+0.1,怎么让它自动转换成高精度运算的程序使得输出尽可能精确
如何计算浮点除法?
expr 4307008 / 4942201rn结果为0
Python浮点计算的坑~
因为Python浮点计算问题,导致在结算商品价格时出现偏差:In [1]: 1999 - int(19.99*100) Out[1]: 1In [2]: int(19.99*100) Out[2]: 1998 解决方式:先计算,再取整。
js浮点计算
function accAdd(h, g) { var f, d, b, j; try { f = h.toString().split(".")[1].length } catch (i) { f = 0 } try { d = g.toString().split(".")[1].length } c
关于java中double的问题
[code=java]rnpublic class DoubleTest rn public static void main(String[] args) rn double d = 6.22;rn String douString1 = "3.12";rn String douString2 = "3.1";rn double d1 = Double.valueOf(douString1);rn double d2 = Double.valueOf(douString2);rn System.out.println(d - d1 - d2);rn rn double a = 26.22;rn String b = "13.12";rn String c = "13.1";rn double e = Double.valueOf(b);rn double f = Double.valueOf(c);rn double ss = Double.valueOf(a) - e - f;rn System.out.println(a - e - f);rn rnrn[/code]rn运行结果:rn-4.440892098500626E-16rn0.0rn这是为什么?
浮点计算找错误。
认真阅读下面回答,看看有没有错误。没有就回答没有。rnrn12.5 rn1. 整数部分12,二进制为1100; 小数部分0.5, 二进制是.1,先把他们连起来,从第一个1数起取24位(后面补0):rn1100.10000000000000000000rn这部分是有效数字。(把小数点前后两部分连起来再取掉头前的1,就是尾数)rn2. 把小数点移到第一个1的后面,需要左移3位, 加上偏移量127:127+3=130,二进制是10000010,这是阶码。rn3. -12.5是负数,所以符号位是1。把符号位,阶码和尾数连起来。注意,尾数的第一位总是1,所以规定不存这一位的1,只取后23位:rn1 10000010 10010000000000000000000rn把这32位按8位一节整理一下,得:rn11000001 01001000 00000000 00000000rn就是十六进制的 C1480000.rnrn2.025675 rn1. 整数部分2,二进制为10; 小数部分0.025675, 二进制是.0000011010010010101001,先把他们连起来,从第一个1数起取24位(后面补0):rn10.0000011010010010101001rn这部分是有效数字。把小数点前后两部分连起来再取掉头前的1,就是尾数: 00000011010010010101001rn2. 把小数点移到第一个1的后面,左移了1位, 加上偏移量127:127+1=128,二进制是10000000,这是阶码。rn3. 2.025675是正数,所以符号位是0。把符号位,阶码和尾数连起来:rn0 10000000 00000011010010010101001rn把这32位按8位一节整理一下,得:rn01000000 00000001 10100100 10101001rn就是十六进制的 4001A4A9.rnrn-1.99744rn还需要详细说吗?rnrn如果只有小数部分,那么需要右移小数点. 比如右移3位才能放到第一个1的后面, 阶码就是127-3=124. rnrn补充一个浮点二进制数手工转换成十进制数的例子:rn假设浮点二进制数是 1011 1101 0100 0000 0000 0000 0000 0000rn按1,8,23位分成三段:rn1 01111010 10000000000000000000000rn最后一段是尾数。前面加上"1.", 就是 1.10000000000000000000000rn下面确定小数点位置。阶码是01111010,加上00000101才是01111111(127),rn所以他减去127的偏移量得-5。(或者化成十进制得122,122-127=-5)。rn因此尾数1.10(后面的0不写了)是小数点右移5位的结果。要复原它就要左移5位小数点,得0.0000110, 即十进制的0.046875rn最后是符号:1代表负数,所以最后的结果是 -0.046875rnrn还要注意其他机器的浮点数表示方法可能与此不同. 不能任意移植.
精确浮点计算
浮点计算 【问题描述】 计算 k *∑(x^i), -m ≤ i ≤ n,精确到小数点后14位(最后要求四舍五入)。 【输入形式】 从文件sigma.in中顺序读入4个由空格分隔的正整数k、x、m、n。(1≤ k、x、m、n ≤ 100)。 【输出形式】 将结果写到标准输出,其中小数占14位,不足部分补零,最后输出一个回车。(输入数据保证输出结果小于2^53。) 【输入样例】 1 10 5 5 【输出样例】 111111.11111000000000 【时间限制】 1s 【空间限制】 65536KB
最新的fpu浮点计算
浮点算法,广泛应用与dsp以及cpu中。在自己进行设计的时候也很有用
JS的浮点计算
        最近在做电商项目的时候,遇到了价格计算的时候,会出现类似欲199.9999999999999999999的情况,但是我明明计算的两个值是只有两位数,怎么会出现这种情况呢? 后来经过查找资料才知道: 比如0.1 + 0.2 = 0.30000000000000004; 这个样子是不是很奇葩; 其实对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++...
二进制浮点转十进制(C#)
二进制浮点数转换成十进制数的详细方法及说明。
请教二进制浮点数据存储格式问题
有个规范ieee754. rn一个实数可表示成SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM但是除了符号位,指数和尾数具体怎么转换成十六进制的? rn比如3.141592654.转换后得到四个16进制数,谁知道步骤
相关热词 c# login 居中 c# 考试软件 c# 自然语言分析 c# 分段读取文件 c# 泛型反射 c#打断点 c# 时间转多少秒 c# 线程函数加参数 c# modbus 读取 c#查询集合表