为什么Android API中有这么多浮动?

为什么Android API中有这么多浮动?,android,floating-point,dalvik,Android,Floating Point,Dalvik,Java中默认的浮点类型是double。如果你在程序中硬编码一个常量,比如2.5,Java会自动将它变成一个双精度的。当您在浮点或整数上执行可能受益于更高精度的操作时,类型将“升级”为双精度 但在安卓API中,从音量到矩形坐标,一切似乎都是一个浮点数。在大多数绘图中使用了一种称为RectF的结构;F代表浮动。对于那些经常将升级的双打转换回(float)的程序员来说,这真是一件痛苦的事情。难道我们都不认为Java代码已经够凌乱和冗长的了吗 在Java中,通常数学协处理器和加速器更喜欢double,

Java中默认的浮点类型是double。如果你在程序中硬编码一个常量,比如
2.5
,Java会自动将它变成一个双精度的。当您在浮点或整数上执行可能受益于更高精度的操作时,类型将“升级”为双精度

但在安卓API中,从音量到矩形坐标,一切似乎都是一个浮点数。在大多数绘图中使用了一种称为
RectF
的结构;F代表浮动。对于那些经常将升级的双打转换回
(float)
的程序员来说,这真是一件痛苦的事情。难道我们都不认为Java代码已经够凌乱和冗长的了吗


在Java中,通常数学协处理器和加速器更喜欢double,因为它对应于一种内部类型。Android的Dalvik虚拟机是否因为某种原因而更喜欢浮动?或者所有的浮动都只是API设计中的扭曲结果吗?

对于不需要太多有效数字(如屏幕偏移量)的度量,使用
double
s而不是
float
s将导致内存效率低下。在移动设备上,最大限度地提高内存消耗效率至关重要,因为在移动设备上,几乎每一种资源都有溢价。而且,在处理像
Rect
s这样的对象时,减少多余的位显然是至关重要的,因为这些对象可能会被数千人分配


我肯定还有其他原因:-)奇怪。《指南》中的性能设计似乎是这样说的:“……桌面系统的常见做法是自由使用浮点……因此,所有关于“float”和“double”的操作都是在软件中执行的……”

这可能有点道理: “…指令不会被无缘无故地限制为特定类型。例如,移动32位寄存器值而不进行解释的指令不必指定它们是移动整数还是移动浮点…”

时,根据CPU的不同,将没有浮点单元(FPU)。因此,它必须在软件上模拟FPU。浮球的速度比双人球快。或者,如果设备有FPU,则使用浮动也可能更快。

我认为Roman是正确的,原因可能主要是为了减少内存使用。考虑到当最终精度不重要时,你将减半数值变量所需的内存。

但请记住,没有必要使用铸造。只需在文本中添加一个F(这样2.5就变成了2.5f)。我不知道编译器是否足够聪明,可以为您执行以下替换,但如果没有,这也会使您的代码稍微更高效

考虑

float x = (float) 2.5;


在第一种情况下,在运行时,程序存储double,然后在存储结果浮点值之前执行强制转换操作。在第二种情况下,编译器会将该值识别为浮点值,因此在运行时,您既可以避免存储double(尽管可能是暂时的),也可以避免强制转换操作(因为它已经存储为浮点值)。

在没有FPU的设备上,单精度浮点运算比双精度等效运算快得多。因此,Android框架提供了一个FloatMath类,该类复制了一些java.lang.Math函数,但使用了float参数而不是double

在最近安装了FPU的Android设备上,单精度和双精度操作所需的时间大致相同,并且明显快于软件实现。(为性能而设计页面是为G1编写的,需要更新以反映各种变化。)


顺便说一句,写“2.5f”或(float)2.5“并不重要。不管怎样,javac都知道您需要一个单精度浮点常量,这就是它生成的结果。您可以通过编写一个示例程序并检查生成的字节码来验证这一点。

这是最接近正确原因的,来自开发人员。这不是真正的记忆。ARMs没有FPU,或者有32位FPU的ARMs。64位双精度模拟的速度很慢。来自“fadden”(编写VM的人之一)的另一个答案是最好的答案。更正-在现代设备上,浮点和双精度是等效的。我已经为froyo重写了大多数“性能设计”。Droid和Nexus One等现代设备都有浮点硬件,这意味着浮点/双精度的除法实际上比整数/长精度的除法快(因为还没有硬件整数除法)。Dalvik字节码文档中的注释更多地涉及指令集的设计和代码验证。其思想是,在内部,我加载的寄存器是“整型常量”0还是“浮点常量”0是无关的;它只是一个32位的值。与浮动、双精度或性能无关。你确定吗?我刚刚测试过,两个版本都生成相同的字节码。看法登的回答。@Oliv-fadden跟在我后面回答,我想我已经说清楚了,不,我不确定。考虑一下“我不知道是否有编译器……”当没有任何双打开始的时候,浮标或惯性队何时被提升为双打?
float x = 2.5f;