Java中的Float和double数据类型

时间:2014-12-22 07:11:39

标签: java floating-point double ieee-754

浮点数据类型是单精度32位IEEE 754浮点数,双数据类型是双精度64位IEEE 754浮点数。

这是什么意思?什么时候应该使用float而不是double,反之亦然?

8 个答案:

答案 0 :(得分:236)

Wikipedia page就是一个很好的起点。

总结一下:

  • float以32位表示,带有1个符号位,8位指数和23位有效数字(或者从科学数字符号开始:2.33728 * 10 12 ; 33728是有效数字。

  • double以64位表示,带有1个符号位,11位指数和52位有效数。

默认情况下,Java使用double来表示其浮点数字(因此文字3.14的类型为double)。它也是可以为您提供更大数字范围的数据类型,因此我强烈建议您使用float

某些图书馆可能会强制您使用float,但一般情况下 - 除非您能保证您的结果足够小以适应float' {{ 3}},然后最好选择double

如果您需要准确性 - 例如,您不能使用不准确的小数值(例如1/10 + 2/10),或者您使用货币执行任何 (例如,在系统中代表$ 10.33),然后使用BigDecimal,它可以支持任意数量的精度并优雅地处理这种情况。

答案 1 :(得分:68)

浮动给你约。 6-7十进制数字精度,而双倍给你约。 15-16。双倍的数字范围也更大。

double需要8个字节的存储空间,而float只需4个字节。

答案 2 :(得分:13)

在计算需要小数精度的表达式时,将使用浮点数(也称为实数)。例如,诸如平方根之类的计算或诸如正弦和余弦之类的超级因子导致其精度需要浮点类型的值。 Java实现了标准(IEEE-754)浮点类型和运算符集。有两种浮点类型,float和double,分别代表单精度和双精度数。它们的宽度和范围如下所示:


   Name     Width in Bits   Range 
    double  64              1 .7e–308 to 1.7e+308
    float   32              3 .4e–038 to 3.4e+038


 的

float类型指定使用32位存储的单精度值。单精度在某些处理器上更快,占用的空间是双精度的一半,但是当值非常大或非常小时,将变得不精确。当您需要小数组件但不需要很高的精度时,float类型的变量很有用。

以下是一些示例浮点变量声明:

浮动hightemp,lowtemp;


 的

双精度,由double关键字表示,使用64位来存储值。在一些针对高速数学计算进行了优化的现代处理器上,双精度实际上比单精度更快。所有超越数学函数(如sin(),cos()和sqrt())都返回double值。当您需要在许多迭代计算中保持准确性或正在操纵大值数字时,double是最佳选择。

答案 3 :(得分:1)

根据IEEE标准,float是实数的32位表示,而double是64位表示。

在Java程序中,我们通常会看到使用双数据类型。它只是为了避免溢出,因为使用double数据类型可以容纳的数字范围大于使用float时的范围。

当需要高精度时,鼓励使用双精度。很久以前实现的很少的库方法仍然需要使用float数据类型(这只是因为它是使用float实现的,没有别的!)。

但是,如果您确定您的程序需要较小的数字并且使用float时不会出现溢出,那么使用float将大大提高您的空间复杂度,因为浮点数需要一半的内存,因为double需要

答案 4 :(得分:0)

此示例说明如何从Java中的浮点数中提取符号(最左边的位),指数(后跟8位)和尾数(最右边的23位)。

int bits = Float.floatToIntBits(-0.005f);
int sign = bits >>> 31;
int exp = (bits >>> 23 & ((1 << 8) - 1)) - ((1 << 7) - 1);
int mantissa = bits & ((1 << 23) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Float.intBitsToFloat((sign << 31) | (exp + ((1 << 7) - 1)) << 23 | mantissa));

同样的方法可以用于double(11位指数和52位尾数)。

long bits = Double.doubleToLongBits(-0.005);
long sign = bits >>> 63;
long exp = (bits >>> 52 & ((1 << 11) - 1)) - ((1 << 10) - 1);
long mantissa = bits & ((1L << 52) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Double.longBitsToDouble((sign << 63) | (exp + ((1 << 10) - 1)) << 52 | mantissa));

信用:http://s-j.github.io/java-float/

答案 5 :(得分:0)

这将导致错误:

public class MyClass {
    public static void main(String args[]) {
        float a = 0.5;
    }
}

/MyClass.java:3:错误:不兼容的类型:可能从双精度转换为浮点型         浮动a = 0.5;

这将很好地工作

public class MyClass {
    public static void main(String args[]) {
        double a = 0.5;
    }
}

这也可以很好地工作

public class MyClass {
    public static void main(String args[]) {
        float a = (float)0.5;
    }
}

原因:默认情况下,Java将实数存储为两倍以确保更高的精度。

Double占用更多空间,但计算时更精确; float占用更少空间,但精度不高。

答案 6 :(得分:0)

对于精确计算,应使用double而不是float;而在使用不太精确的计算时,请使用float而不是double。浮点数仅包含十进制数,而双精度数包含IEEE754双精度浮点数,这使得更容易包含和计算数字。希望这会有所帮助。

答案 7 :(得分:0)

在常规编程计算中,我们不使用浮点数。如果确保结果范围在float数据类型的范围内,则可以选择float数据类型以节省内存。通常,我们使用double的原因有两个:-

  • 如果我们要使用浮点数作为浮点数据类型,则方法调用者必须显式后缀F或f,因为默认情况下,每个浮点数都被视为双精度。这增加了程序员的负担。如果我们将浮点数用作双精度数据类型,则无需添加任何后缀。
  • 浮点型是单精度数据类型,意味着它占用4个字节。因此,在大型计算中,我们将无法获得完整的结果。如果我们选择double数据类型,则它将占用8个字节,我们将获得完整的结果。

float和double数据类型都是专门为科学计算而设计的,在这种计算中,近似误差是可以接受的。如果精度是最优先考虑的问题,则建议使用BigDecimal类而不是float或double数据类型。来源:-Chrome's DevTools selector