简体   繁体   English

int和double除以double java

[英]int and double divided by double java

How do I explain the below: 我如何解释以下内容:

    double o = 2.3;
    int i = (int) (o * 100000.0);
    double d = i / 100000.0;
    System.out.println(d);

prints 2.29999 打印2.29999

    double o = 2.3;
    double i = o * 100000.0;
    double d = i / 100000.0;
    System.out.println(d);

prints 2.3 版画2.3

When dividing an int by double doesn't java first cast the int as a double then do the division - if so the two code blocks should effectively print the same value? 当将int除以double时,java不会先将int转换为double,然后进行除法-如果这样,则两个代码块应有效地打印相同的值?

There seems to be some IEEE 754 floating point precision specifications I'm missing and/or jvm optimizations that inlines 我似乎缺少一些IEEE 754浮点精度规范和/或内联的jvm优化

 double i = 2.3 * 100000.0;
 double d = i / 100000.0;

as double d = 2.3 * 100000.0 / 100000.0; 作为double d = 2.3 * 100000.0 / 100000.0; effectively cancelling out the division and making this a no-op. 有效地消除了分歧,使之成为无人值守。

Thoughts? 有什么想法吗?

2.3 is not exactly representable in IEEE-754 64-bit binary floating-point. 在IEEE-754 64位二进制浮点中不能完全表示2.3。 What happens in your first code sequence is: 在您的第一个代码序列中发生的是:

  • The source text 2.3 is converted to the nearest representable value, 2.29999999999999982236431605997495353221893310546875. 源文本2.3转换为最接近的可表示值2.29999999999999989982236431605997495353221893310546875。
  • The exact mathematical result of multiplying that by 100000 is not exactly representable either, so it is rounded to 229999.99999999997089616954326629638671875. 将其乘以100000的确切数学结果也无法完全表示,因此将其舍入为229999.99999999997089616954326629638671875。
  • When this is converted to an int , the conversion truncates, producing 229999. 将其转换为int ,转换将截断,并产生229999。
  • Dividing that by 100000 rounds again, producing 2.29999000000000020094148567295633256435394287109375. 再将其除以100000轮,产生2.29999000000000020094148567295633256435394287109375。
  • When the above is printed, Java displays it as “2.29999”. 打印以上内容时,Java将其显示为“ 2.29999”。

There seems to be some IEEE 754 floating point precision specifications I'm missing 我似乎缺少一些IEEE 754浮点精度规范

When you use (int) it truncates the fractional part no matter how close it is to the next whole value. 使用(int) ,无论小数部分与下一个整数值有多接近,它都会截断小数部分。 It is not reversible as information is lost, so it should be no surprise that you don't get the same result. 由于信息丢失,它是不可逆的,因此获得相同的结果也就不足为奇了。

What you could do instead is the following 您可以做的是以下操作

double o = 2.3;
long l = Math.round(o * 100000.0);
double d = l / 100000.0;
System.out.println(d);

jvm optimizations that inlines ... making this a no-op 内联的jvm优化...使其成为无操作

The JVM might optimise it, but it won't change the result. JVM可能对其进行了优化,但不会改变结果。 If an optimisation changes the outcome it is a bug in the optimiser. 如果优化改变了结果,那是优化器中的错误。

double i = o * 100000.0;

The value of i after this is 229999.99999999997 (you can see this yourself by adding a simple print statement; it's due to floating-point inaccuracies ). 之后的i值为229999.99999999997 (您可以通过添加一个简单的print语句来自己查看;这是由于浮点数不正确造成的 )。

int i = (int) (o * 100000.0);

The value of i after this is 229999 (ie the value above with the fractional part truncated due to the int cast). 之后的i值为229999 (即,上面的值(小数部分由于int而被截断))。

Therefore, in the line 因此,在行中

double d = i / 100000.0;

you are using two numerically different i values in your two snippets (ie they differ by about 1), hence the different outputs. 您在两个摘要中使用了两个数值不同的i值(即,它们相差约1),因此输出也不同。

You are correct in saying that when dividing an int by a double, the int is first converted to a double (this is done through the bytecode instruction i2d ). 您的说法正确,是将int除以double时,首先将int转换为double(这是通过字节码指令i2d来完成的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM