关于浮点:Java中的Float和double数据类型

Float and double datatype in Java

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

这是什么意思?什么时候我应该使用浮动而不是双精度呢,反之亦然?


维基百科页面是一个很好的开始。

总而言之:

  • float用32位表示,有1个符号位、8个指数位和23个有效位(或从科学记数法中得出的值:2.33728*1012;33728是有效位)。

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

默认情况下,Java使用EDCOX1 OR 1表示它的浮点数字(因此,文本EDCOX1 OR 3)键入EDCOX1〔1〕)。它也是一种数据类型,可以为您提供更大的数字范围,因此我强烈建议您在float上使用它。

有些库可能会强迫您使用float,但一般来说,除非您能保证结果足够小,能够满足float的规定范围,否则最好选择double

如果您需要准确度,例如,您不能有不准确的十进制值(如1/10 + 2/10),或者您正在使用货币(例如,在系统中表示10.33美元),然后使用BigDecimal,它可以支持任意数量的精度并优雅地处理类似情况。


一个浮点数给你6-7位的精度,而一个双精度则给你15-16位的精度。同样,对于double,数字的范围更大。

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


浮点数,也称为实数,用于计算需要分数精度的表达式。例如,计算(如平方根)或超越(如正弦和余弦)会生成精度要求浮点类型的值。Java实现了浮点类型和运算符的标准(IEEE - 754)集。浮点类型有两种,float和double,分别表示单精度数和双精度数。其宽度和范围如下所示:

< BR>

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

< BR>浮动

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

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

浮球高温、低温;

< BR>双重的

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


尽管如此,Java似乎偏向于使用双重计算。

举个例子,我今天早些时候写的程序,当我使用float时,这些方法不起作用,但是当我用double替换float(在netbeans-ide中)时,它们的效果非常好:

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
package palettedos;
import java.util.*;

class Palettedos{
    private static Scanner Z = new Scanner(System.in);
    public static final double pi = 3.142;

    public static void main(String[]args){
        Palettedos A = new Palettedos();
        System.out.println("Enter the base and height of the triangle respectively");
        int base = Z.nextInt();
        int height = Z.nextInt();
        System.out.println("Enter the radius of the circle");
        int radius = Z.nextInt();
        System.out.println("Enter the length of the square");
        long length = Z.nextInt();
        double tArea = A.calculateArea(base, height);
        double cArea = A.calculateArea(radius);
        long sqArea = A.calculateArea(length);
        System.out.println("The area of the triangle is\t" + tArea);
        System.out.println("The area of the circle is\t" + cArea);
        System.out.println("The area of the square is\t" + sqArea);
    }

    double calculateArea(int base, int height){
        double triArea = 0.5*base*height;
        return triArea;
    }

    double calculateArea(int radius){
        double circArea = pi*radius*radius;
        return circArea;
    }

    long calculateArea(long length){
        long squaArea = length*length;
        return squaArea;
    }
}


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

在Java程序中,我们通常主要看到双数据类型的使用。这只是为了避免溢出,因为使用双数据类型可以容纳的数字范围比使用浮点时的范围要大。

当需要高精度时,鼓励使用双精度。很久以前实现的一些库方法仍然需要使用float数据类型作为必需(这仅仅是因为它是使用float实现的,而不是其他的!).

但是,如果您确定您的程序需要较小的数字,并且使用float不会发生溢出,那么使用float将大大提高您的空间复杂性,因为float需要双倍内存的一半。


这将导致错误:

1
2
3
4
5
public class MyClass {
    public static void main(String args[]) {
        float a = 0.5;
    }
}

Java:3:错误:不兼容类型:可能的有损转换从双到浮动浮动A=0.5;

这个很好用

1
2
3
4
5
public class MyClass {
    public static void main(String args[]) {
        double a = 0.5;
    }
}

这也很好用

1
2
3
4
5
public class MyClass {
    public static void main(String args[]) {
        float a = (float)0.5;
    }
}

原因:Java默认存储实数为双,以确保更高的精度。

double在计算时占用更多空间,但更精确,float占用的空间更少,但精度更低。


这个例子说明了如何从Java中的浮点中提取符号(最左边的位)、指数(以下8个位)和尾数(23个最右边的位)。

1
2
3
4
5
6
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位尾数)。

1
2
3
4
5
6
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/