首页 文章

Java中的Float和double数据类型

提问于
浏览
184

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

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

7 回答

  • 218

    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 ),或者你正在使用货币 anything (例如,在系统中代表$ 10.33),那么使用 BigDecimal ,它可以支持任意数量的精度并优雅地处理这种情况 .

  • 64

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

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

  • 0

    在计算需要小数精度的表达式时,将使用浮点数(也称为实数) . 例如,诸如平方根之类的计算或诸如正弦和余弦之类的超级因子导致其精度需要浮点类型的值 . 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

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

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

    浮动hightemp,lowtemp;

    double

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

  • 11

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

    我在今天早些时候编写的程序就是这样,当我使用float时这些方法不起作用,但是当我用float替换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;
        }
    }
    
  • 0

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

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

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

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

  • 2

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

    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/

  • 1

    This will give error:

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

    /MyClass.java:3:错误:不兼容的类型:可能有损转换从double到float float a = 0.5;

    This will work perfectly fine

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

    This will also work perfectly fine

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

    Reason :Java默认将实数存储为double,以确保更高的精度 .

    双倍占用更多空间但在计算过程中更精确,浮动占用的空间更少,但精度更低 .

相关问题