Java 如何将浮点值舍入为双倍值?

Java 如何将浮点值舍入为双倍值?,java,floating-point,double,rounding,rounding-error,Java,Floating Point,Double,Rounding,Rounding Error,以下代码不适用于人类: double d = 0.7F; System.out.println( d ); 打印值:0.69999988079071 以下代码工作得更好: double d = Double.valueOf( Float.toString( 0.7F )); System.out.println( d ); 但是创建一个额外的字符串。在没有额外字符串的情况下,是否有更高性能的浮点到双精度的转换 代码行很简单,只演示问题。这个程序更复杂。浮点值位于复杂模型的一部分中。格式化层仅

以下代码不适用于人类:

double d = 0.7F;
System.out.println( d );
打印值:0.69999988079071

以下代码工作得更好:

double d = Double.valueOf( Float.toString( 0.7F ));
System.out.println( d );
但是创建一个额外的字符串。在没有额外字符串的情况下,是否有更高性能的浮点到双精度的转换

代码行很简单,只演示问题。这个程序更复杂。浮点值位于复杂模型的一部分中。格式化层仅使用双精度。此外,DecimalFormat仅接受双精度格式,不接受浮点格式。

是,使用

double d = 0.7D;
使用F意味着它是一个浮点常量,然后它被提升为double,可能不是可以用双精度浮点表示的最接近0.7的数字,因为尾数没有以任何方式扩展


0.7D首先是一个双常数。

如果它是关于人类的输出,我建议使用printf:

System.out.printf("Value: %.2f", d);
使用FloatingDecimal进行转换肯定更快,而且还可以打印0.7

  Double doubleResult = new FloatingDecimal(0.7F).doubleValue();
但是创建一个额外的字符串。在没有额外字符串的情况下,是否有更高性能的浮点到双精度的转换

分配几个字节的短期块只是冰山一角。您所希望的“转换”基本上需要从二进制浮点转换为十进制表示,然后再转换回二进制浮点,而这些转换并不便宜,无论中间十进制表示是如何存储的

如果您知道您关心的浮点值来自点后两位的十进制值,您可以使用:

double d = Math.round(f * 100.0) / 100.0;

这只需要一次除法加上Math.round,这比一次十进制转换要便宜。任何好的编译器都应该为它生成不分配的代码。

如果你知道你想要的精度,你可以将它四舍五入到小数点后6位。例如

public static double round6(double x) {
    return Math.round(x * 1e6) / 1e6;
}

round6(0.7f) == 0.7
如果精度合适,那么传入的x是一个浮点值这一事实并不重要

double d = 0.7F;
System.out.println( d );
打印值:0.69999988079071

转换是正确的

当您打印出一个浮点f时,它会打印出足够的数字,以便打印出的值比任何其他浮点更接近f的真实值

当你打印出一个double时,它会打印出足够的数字,这样它打印出来的值会比其他任何double更接近d的真值


从float到double的转换是精确的,它只是向您显示一个更接近您在float中拥有的真实值的值。Double.valueOf Float.toString 0.7F不是更精确;它只是假装你的价值观比实际更好。

如果结果是适合人类的,那么在我看来,只有当价值观通过println呈现给人类时才有意义。在这一点上,应用表示输出中所需精度级别的格式是很简单的。在这种情况下,您希望以特殊方式从float转换为double有什么特殊的原因吗?这些值在Swing GUI中表示,并使用只接受double的十进制格式进行格式化。还有其他双精度源。模型中的值和GUI中的表示之间存在大量API调用。代码仅演示了问题。这些值保存在模型中。这取决于您如何看待它。当然,不会擦除任何位。但尾数并没有延长。因此,它不是可以用双精度浮点表示的最接近0.7的数字。如果你直接解析它,你就失去了你能得到的精度。@ HORCARX7,那么你应该仔细考虑为什么你要用单精度工作一部分时间,部分时间用双精度。如果精度对您很重要,您应该从一开始就以双精度保存数据。如果您真的想保留浮点数据并对其使用双重操作,那么实际上,您所能做的就是在最后正确格式化它。在浮点值和println之间,DecimalFormat.formatdouble是大约20个具有双精度的API调用。这里可能使用FloatingDecimal,尽管它的sun.missay表示,选择浮点类型是为了表示一个十进制数,该十进制数在一段代码中只有很少的有效数字,而您没有编写该代码,并且无法更改该代码。现在假设选择了double类型来表示一个数字,该数字将以十进制显示,并带有区分double所需的尽可能多的小数,同样是在一段您未编写且无法更改的代码中。我相信这就是OP所处的情况。