Java中的浮点和双精度数据类型

koaltpgm  于 2022-11-27  发布在  Java
关注(0)|答案(9)|浏览(180)

float数据类型是单精度32位IEEE 754浮点,double数据类型是双精度64位IEEE 754浮点。
什么意思?什么时候应该使用float而不是double,反之亦然?

6pp0gazn

6pp0gazn1#

上面的Wikipedia page是一个很好的起点。
总而言之:

  • float以32位表示,其中1位符号位、8位指数位和23位有效位(或科学记数法数字的后续值:2.33728 × 1012; 33728是有效数)。
  • double以64位表示,其中1位符号位、11位指数位和52位有效位。

默认情况下,Java使用double来表示它的浮点数(因此文字3.14的类型为double)。它也是一种数据类型,可以给予更大的数字范围,所以我强烈建议在float上使用它。
可能有一些库会强制你使用float,但一般来说--除非你能保证你的结果足够小,可以放入floatprescribed range,那么最好选择double
如果您需要精确性--例如,您不能有不精确的十进制值(如1/10 + 2/10),或者您正在做任何与货币有关的事情(例如,在系统中表示10.33美元),那么请使用BigDecimal,它可以支持任意数量的精确度,并且可以优雅地处理类似的情况。

h22fl7wq

h22fl7wq2#

浮点型的精度大约为6-7位小数,而双精度型的精度大约为15-16位。双精度型的数字范围也更大。
一个double需要8字节的存储空间,而float只需要4字节。

yqkkidmi

yqkkidmi3#

浮点数(也称为真实的)在计算需要分数精度的表达式时使用。例如,平方根之类的计算或正弦和余弦之类的超越运算会产生精度需要浮点类型的值。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类型的变量在需要小数部分但不需要很高精度时很有用。
下面是一些浮点变量声明示例:
浮动高温、低温;

双倍

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

k97glaaz

k97glaaz4#

这将给予错误:

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

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

双精度占用的空间较多,但计算时精度较高;浮点占用的空间较少,但精度较低。

whhtz7ly

whhtz7ly5#

尽管如此,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;
    }
}
kgsdhlau

kgsdhlau6#

根据IEEE标准,浮点数是真实的的32位表示,而双精度数是64位表示。
在Java程序中,我们通常会看到double数据类型的使用。这只是为了避免溢出,因为使用double数据类型可以容纳的数字范围比使用float时的范围要大。
当需要高精度的时候,也鼓励使用double。很少有很久以前实现的库方法仍然要求必须使用float数据类型(这仅仅是因为它是使用float实现的,没有别的!)。
但是如果你确定你的程序需要的是小数字,并且使用float不会发生溢出,那么使用float将大大改善你的空间复杂性,因为float需要的内存是double的一半。

gpfsuwkq

gpfsuwkq7#

这个例子说明了如何在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));

同样的方法可以用于双精度(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/

xqk2d5yq

xqk2d5yq8#

对于精确计算,您应该使用double而不是float,而在使用不太精确的计算时,则应该使用float而不是double。Float只包含十进制数字,而double包含IEEE754双精度浮点数,这样更容易包含和更精确地计算数字。希望这对您有所帮助。

wbgh16ku

wbgh16ku9#

在常规的编程计算中,我们不使用浮点数。如果我们确保结果范围在浮点数数据类型的范围内,那么我们可以选择浮点数数据类型以节省内存。通常,我们使用双精度浮点数是因为两个原因:

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

float和double数据类型都是专门为科学计算设计的,在科学计算中,近似误差是可以接受的。如果精度是最重要的考虑因素,那么建议使用BigDecimal类,而不是float或double数据类型。源:-Float and double datatypes in Java

相关问题