分享
为什么问答平台  ›  专栏  ›  技术社区  ›  Roman

Java有什么目的是一个浮点基元类型? - For what purpose does java have a float primitive type?

  •  20
  • Roman  · 技术社区  · 1 周前

    你能帮助我阐明Java中浮点原语的用法吗?

    我的理解是,将浮点值转换为double,反之亦然,这是有问题的。我读到(很久以前,不确定在新的JVM中是否真的是这样),float的性能比double差得多。当然,float的精度比double低。

    我还记得,当我使用awt和swing时,我在使用float或double时遇到了一些问题(比如使用point2d.float或point2d.double)。

    因此,我只看到浮于双的两个优点:

    1. 它只需要4个字节,而double需要8个字节

    2. Java内存模型(JMM)保证赋值操作是带有浮点变量的原子,而不是双原子的原子操作。

    还有其他浮动比双倍更好的情况吗?在应用程序中是否使用浮动?

    5 回复  |  直到 2 年前
        1
  •  15
  •   Neil Coffey    8 年前

    在某种程度上,包含浮点类型的原因是历史性的:它代表了一种标准的IEEE浮点表示法,从那时起,为了获得极低的精度而从浮点数字的大小中去掉4个字节,这是一种值得权衡的做法。

    如今,浮点数的用途相当有限。但是,例如,拥有数据类型可以更容易地编写需要与使用浮动的旧系统进行互操作的代码。

    就性能而言,我认为float和double本质上是相同的 除分部业绩外 . 通常,无论您使用哪种格式,处理器都会转换为其内部格式,进行计算,然后再次转换回来,实际计算实际上需要固定的时间。在除法的情况下,至少在英特尔处理器上,我记得做除法所花费的时间通常是每2位精度一个时钟周期,所以无论您使用浮点还是双精度都会有区别。

    除非您真的有充分的理由使用它,否则在新代码中,我通常会避免使用“float”。

        2
  •  7
  •   mmr    8 年前

    你刚才给出的两个理由是巨大的。

    如果你有一个3dvolume,1K乘1K乘64,然后有很多时间点的数据,然后想做一个最大强度的投影电影,事实上,浮动是双倍大小的一半,这可能是快速完成和震荡之间的区别,因为你没有内存。

    从线程的角度来看,原子性也是巨大的。

    在速度/性能和准确度之间总会有一个权衡。如果你有一个小于2^31的数字和一个整数,那么一个整数总是比一个浮点更好地表示这个数字,仅仅是因为精度损失。您必须评估您的需求,并为您的问题使用适当的类型。

        3
  •  3
  •   mdma    8 年前

    我想当你提到存储的时候,你就已经把它钉牢了,浮点数是它的一半。

    对于处理大量浮点数数组的应用程序来说,使用浮点数比使用双精度浮点数可能会显示出更好的性能,因此内存带是限制因素。通过切换到 float[] double[] 而将数据大小减半,则有效地使吞吐量增加一倍,因为在给定的时间内可以获取两倍的值。虽然CPU有更多的工作要做,将浮点转换为双精度浮点,但这与内存提取并行进行,提取需要更长的时间。

    对于某些应用程序,精度损失可能值得交易以获得性能收益。然后又…-)

        4
  •  2
  •   Jørgen Fogh    8 年前

    的确,在某些情况下,double的操作速度可能比float快。但是,这要求所有内容都适合一级缓存。有了浮点数,在缓存行中的数量可以增加一倍。这可以使一些程序的运行速度快两倍。

    SSE指令也可以使用4个并行浮点而不是2个浮点,但我怀疑JIT实际上使用了这些浮点。不过,我可能错了。

        5
  •  2
  •   Geoff    8 年前

    是的,浮动的优点是:

    1. 只需要4个字节
    2. 原子分配
    3. 算法应该更快,特别是在32位体系结构上,因为有特定的浮点字节代码。

    使用双打时缓解这些问题的方法:

    1. 多买点公羊,真便宜。
    2. 如果需要原子分配,请使用volatile double。
    3. 做测试,验证每个测试的性能,如果一个测试真的更快,那么就没有很多可以做的了。

    还有人提到,这类似于short和int参数,但事实并非如此。除了存储在数组中的所有整数类型(包括布尔型)之外,Java内存模型中都存储为4字节整数。