float vs double

float和double都可以表示浮点类型,但是它们可以表示的数据类型范围和精度是不同的。下面的代码便演示了这两种数据类型在一些场景下的差别。

 1  int a = 1219;
 2  int b = 56;
 3  __int64 c = 1503050028000;
 4  int d = 1000;
 5  float e = 0.883889;
 6
 7
 8  __int64 r1 = c + __int64((a - b))*d / e;
 9
10  __int64 r2 = __int64((a - b))*d / e;
11
12  __int64 r3 = c + r2;

这段代码运行后,结果是:

r1=1503051382784

r2=1315776

r3=1503051343776

这不科学,小学三年级的学生都知道这不对。

让我们来看看编译器是如何处理这段代码的吧。

执行完第8行代码前:

执行完第8行代码后:

我们看到,编译器使用了CVTSD2SS指令将__int64类型转换为了float类型。正是这一转换过程,导致了精度的丢失。数值从原来的1503050028000变成了1503050152687.

最终的执行结果:

我们看到,不仅c的值发生了变化,__int64((a - b))*d=1163000的值也发生了变化。只是这个变化比较小,对最终的结果影响不大而已。

解决办法1:将float转换为double

解决办法2:如同办法1,将算术运算分成多行,结果也正确。因为__int64并不会被转换为flloat从而丢失精度了。

所以,float和double的精度差别以及可表示的数值范围确实对数据的运算结果有着很大影响。

时间: 2024-08-27 05:29:44

float vs double的相关文章

Java中的简单浮点数类型float和double不能够进行精确运算

在java中,简单的浮点类型float和double是不能够进行运算.我们先看下面的两个程序代码: 代码一: import java.util.Scanner; class Circle { double radius; static final double PI=3.14; public Circle(){this.radius=0;} public Circle(double r){this.radius=r;} public double getArea(){return PI*this

Java 浮点数 float或double类型的表示范围和精度

隐约记得,浮点数判断大小好像有陷阱,因为底层的二进制数不能精确表示所有的小数.有时候会产生让人觉得莫名其妙的事情. 如在java中, 0.99999999f==1f //true 0.9f==1f //false 要明白这些,首先要搞清楚float和double在内存结构 1.内存结构 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bits(尾数位) dou

Java中浮点型数据Float和Double进行精确计算的问题

一.浮点计算中发生精度丢失  大概很多有编程经验的朋友都对这个问题不陌生了:无论你使用的是什么编程语言,在使用浮点型数据进行精确计算时,你都有可能遇到计算结果出错的情况.来看下面的例子. // 这是一个利用浮点型数据进行精确计算时结果出错的例子,使用Java编写,有所省略. double a = (1.2 - 0.4) / 0.1;System.out.println(a); 如果你认为这个程序的输出结果是“8”的话,那你就错了.实际上,程序的输出结果是“7.999999999999999”.好

float与double的范围和精度

1 范围 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bits(尾数位) double: 1bit(符号位) 11bits(指数位) 52bits(尾数位) 于是,float的指数范围为-127~+128,而double的指数范围为-1023~+1024,并且指数位是按补码的形式来划分的.其中负指数决定了浮点数所能表达的绝对值最小的非零数:而正指数决定了浮

java控制float和double的精度

在做读取Excel表格数据时,碰到有小数点的数字,用double和float来求和时会多出好多位小数,看起来总觉得怪怪的,怎样控制它的长度呢? DecimalFormat df = new DecimalFormat("########.0"); //四舍五入 value = Double.parseDouble(df.format(value)); 我这里是控制一位小数,如果要求两位,就写成########.00 java控制float和double的精度,布布扣,bubuko.co

金融、支付行业的开发者不得不知道的float、double计算误差问题

在大多数行业涉及到浮点数的计算的场景比较少,但是在金融.支付行业就比较多了,而且在这两个行业一个小小的错误 可能将会给公司带来极大的损失. 以前我们公司就出现了这样的一个问题,当时使用的是double类型进行计算,导致计算出来的结果与实际的结果少了几十 元钱.虽然数额不大,但是引起产品.技术的重视.通过查阅相关资料,终于知道了是因为float.double在对含有小数的数值进行 计算过程中的舍入产生了误差. 在浮点运算中,浮点运算很少是精确的.虽然一些数字(譬如 0.5 )可以精确地表示为二进制

java中int,float,long,double取值范围,内存泄露

java中int,float,long,double取值范围是多少? 写道 public class TestOutOfBound { public static void main(String[] args) { System.out.println(Integer.MAX_VALUE-(-Integer.MAX_VALUE)); //内存溢出System.out.println(Integer.MAX_VALUE); //2的31次方-1,10个数位,正的20亿左右,用在钱上面不一定够Sy

C语言中关于float、double、long double精度及数值范围理解

IEEE754浮点数的表示方法.C语言里对float类型数据的表示范围为-3.4*10^38-+3.4*10^38.double为-1.7*10^-308~1.7*10^308,long double为-1.2*10^-4932~1.2*10^4932. 类型 比特(位)数 有效数字 数值范围 float 32 6~7 -3.4*10^38-+3.4*10^38 double 64 15~16 -1.7*10^-308~1.7*10^308 long double 128/ 18~19 -1.2

Java随笔:float、double精确性

通常会用float.double进行货币的计算. 下面这个计算会输出什么? System.out.println(2.00 - 1.10); 开始以为会是0.90,实际结果是:0.8999999999999999 原因在于,不是所有的小数都可以用二进制浮点精确地表示. 如何改造呢? 用int.long进行计算,再转换为浮点数. 用BigDecimal进行计算. System.out.println(new BigDecimal("2.00").subtract(new BigDecim

float及double类型减法运算时精度丢失问题

当float和double类型在进行减法运算时,会出现精度丢失问题,这种问题主要是由于计算机中普遍使用2进制所造成的.在此做为记录,防止日后遗忘.     public static void main(String[] args) {         float a = 2.1f;         float b = 2.0f;         float c = a - b;         System.out.println("a-b=" + c);     }     //输