Java中的浮点和双数据类型

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

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

376955 次浏览

浮点数给你大约。6-7个十进制数字的精度,而双精度给你大约。15 - 16岁。对于double,数字的范围也更大。

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

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

总结如下:

  • float用32位表示,其中1位符号位,8位指数位和23位有效位(或者从科学计数数后面跟随:2.33728*1012;33728是有效值)。

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

默认情况下,Java使用double来表示浮点数(因此字面3.14类型为double)。它也是数据类型,将给你一个更大的数字范围,所以我强烈建议使用float

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

如果你需要精度-例如,你不能有一个不准确的十进制值(如1/10 + 2/10),或者你用货币做任何东西(例如,在系统中表示$10.33),那么使用BigDecimal,它可以支持任意数量的精度,并优雅地处理此类情况。

浮点数,也称为实数,用于计算要求分数精度的表达式。例如,像平方根这样的计算,或者像正弦和余弦这样的先验运算,会产生一个精度要求浮点类型的值。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
< p >
< / >强浮动

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

下面是一些浮动变量声明的例子:

浮动高温度,低温度;

< p >
双< / >强

Double precision(由Double关键字表示)使用64位来存储值。在一些为高速数学计算而优化的现代处理器上,双精度实际上比单精度更快。所有先验数学函数,如sin()、cos()和sqrt(),都返回双值。当您需要在多次迭代计算中保持精度时,或者需要处理大数值时,double是最好的选择。

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

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

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

但是如果你确定你的程序需要很小的数字,并且使用float不会发生溢出,那么使用float将极大地提高你的空间复杂性,因为float所需要的内存是所需要的两倍。

尽管如此,Java似乎倾向于使用double进行计算:

以我今天早些时候写的程序为例,当我使用float时,这些方法不起作用,但现在当我用double替换float时工作得很好(在NetBeans IDE中):

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;
}
}

这个例子演示了如何从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/

这将给出错误:

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

/MyClass.java:3:错误:不兼容的类型:可能的有损转换从double到float 浮动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以确保更高的精度。

在计算过程中,Double占用更多空间但更精确,float占用更少空间但更精确。

你应该使用double而不是float进行精确的计算,使用float而不是double进行不精确的计算。Float只包含十进制数,但double包含一个IEEE754双精度浮点数,使其更容易包含和更准确地计算数字。希望这能有所帮助。

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

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

float和double数据类型都是专门为科学计算设计的,在科学计算中,近似误差是可以接受的。如果精度是最优先考虑的问题,那么建议使用BigDecimal类而不是float或double数据类型。来源:Java中的浮点和双数据类型