对整数和浮点除法的结果应用转换:这里发生了什么? [英] Applying casts to the results of integer and floating point division: what's going on here?

查看:177
本文介绍了对整数和浮点除法的结果应用转换:这里发生了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是个初学者,对我来说没什么意义。请解释一下我的错在哪里。对不起,如果这之前已经问过。



这里小数点的存在意味着这些使用浮点除法进行评估。

  System.out.println(1 / 3.0); //打印:0.3333333333333333 
System.out.println(1.0 / 3); //打印:0.3333333333333333
System.out.println(1.0 / 3.0); //打印:0.3333333333333333

显然,下面是截断整数除法的一个例子。看起来有点奇怪,但确定。

  System.out.println(1/3); //打印:0 

可以这样说:在下面的行中, )cast被评估为1st,它有效地表示:将1/3视为双精度 - 不要使用截断整数除法。而是使用浮点除法。

  System.out.println((double)1/3); //打印出来:0.3333333333333333 

然而,我们得到了0.0 - 这是怎么发生的呢?

  System.out.println((double)(1/3)); //打印出来:0.0 

好的,也许额外的圆括号表示(1/3) 1。这是使用截断整数除法产生0.然后然后双应用给我们0.0好吧,这是有道理的



好吧,所以我们也许可以规则1:(双)表达式意味着首先应用(双重)强制转换,然后评估表达式。

$ b

规则2:(double)(表达式)表示评估表达式然后应用转换。
$!

所以在下面的一行中我们有:(int)表达式,所以我想我们可以应用规则1)。 (int)强制类型被评估为1st。它实际上是这样说的:把1.0 / 3当作一个整数 - 不要使用与double相同的内存,不要使用浮点除法,而是应用截断整数除法。所以我们有0对吗?


$ b $ pre $ System.out.println((int)1 / 3.0); //这个输出:0.3333333333333333

好,所以我们有0.33333,所以(int)强制类型不会被赋值为1,就好像它不在那里。让我们提出第三条规则:(b)规则3:(int)表达式意味着忽略(int)类型转换,就像(int)甚至不存在。/ b>

对于下面的代码,使用规则3,我们有(int),但是我们只是忽略它,1.0 / 3.0用浮点除法来评估,我们得到0.3333333。成功!

pre $ System.out.println((int)1.0 / 3.0); / /这打印:0.3333333333333333

在下面的最后一行中,我们也有(int),但是我们将忽略它(1.0 / 3)使用浮点除法进行评估,产生0.3333333333对不对? No。

  System.out.println((int)(1.0 / 3)); //打印:0 

现在好了,我很困惑。请问您能帮我把这个问题搞定吗?解决方案

代码基于操作顺序的规则。了解Java认为括号的位置将帮助您理解这种行为。当你说:

 (double)1 / 3.0 

$ p $ ((double)]

1)/ 3.0

这意味着1被转换为双精度值,3.0自动为双精度值,所以你最终会做一个浮点除法,而不是整数除法。同样的事情发生在(double)1/3 上,因为除数是 double ,所以即使dividend是一个 int ,系统意识到你想做浮点除法。编译器不希望你失去精度,除非你特别要求,所以当任何时候被除数或除数是 double ,它都会做 b











$ b

 (int)1 / 3.0 

...就是说:

$ p $ ((int)1)/ 3.0

在这种情况下,您告诉编译器它已经知道:除数(1)是 int 。然后你要求它除以 double 值(3.0)。由于股息是 double ,它将执行 double 除法。



正如你所说的, 1/3 将会产生零,因为这就是整数除法的工作原理,而且这两个数字都是整数。对于 1 /(int)3.0 也是一样的,因为你要让编译器把 3.0 变成(code> 1 /((int)3.0))。 int b
$ b

最后要记住的是(int)0.33 也会被转换为 0 ,因为一个整数不能在其中保存十进制值。所以当你说(int)(1.0 / 3)时,你正在做 double 之后将double重新转换为 int ,产生 0


I'm a beginner and there's something that's not making much sense to me. Please could be so kind as to explain where I'm going wrong. I'm sorry if this has been asked before.

Here the presence of the decimal point mean these get evaluated using floating point division.

System.out.println(1/3.0); // this prints: 0.3333333333333333
System.out.println(1.0/3); // this prints: 0.3333333333333333
System.out.println(1.0/3.0); // this prints: 0.3333333333333333

Apparently, this below is an example of "truncating-integer division." It seems a bit weird to me but ok.

System.out.println(1/3); // this prints: 0

Is it ok to say: "in the line below, the (double) cast is evaluated 1st. It effectively says: "treat 1/3 as a double - don't use truncating integer division. instead use floating point division.""

System.out.println((double)1/3); // this prints: 0.3333333333333333

Below, however we get 0.0 - how did that happen?

System.out.println((double)(1/3)); // this prints: 0.0

ok so maybe the extra parentheses mean the (1/3) gets evaluated 1st. It is evaluated using truncating integer division yielding 0. And then the double is applied giving us 0.0 Ok that makes sense

Ok so we maybe can propose a couple of general rules here:

Rule 1: (double) expression means apply the (double) cast first then evaluate the expression.

Rule 2: (double) (expression) means evaluate the expression then apply the cast. Great!

So in the next line below we have: (int) expression, so I guess we can apply rule 1). The (int) cast is evaluated 1st. It effectively says: "treat 1.0/3 as a int - don't use as much memory as you would with a double. Don't use floating point division, instead apply truncating integer division."" So we have 0 right? No.

System.out.println((int)1/3.0); // this prints: 0.3333333333333333

Ok so we have 0.33333 so the (int) cast is not evaluated 1st. It is as if it wasn't there. Let's propose a 3rd rule:

Rule 3: (int) expression means ignore the (int) cast altogether just evaluate the expression like the (int) isn't even there.

Ok applying rule 3 to the line below, we have (int) but we are just going to ignore it. 1.0/3.0 is evaluated with floating point division and we get 0.3333333. Success!

System.out.println((int)1.0/3.0); // this prints: 0.3333333333333333

And in the last line below, again we have (int) but we are just going to ignore it. (1.0/3) is evaluated using floating point division yielding 0.3333333333 right? No.

System.out.println((int)(1.0/3)); // this prints: 0

Ok now I'm confused. Please could you help me get my head round this?

解决方案

Java's language parsing rules are basically implying a lot of parentheses everywhere in your code based on its rules of order of operations. Understanding where Java thinks the parentheses are will help you understand this behavior. When you say:

(double) 1 / 3.0

... this is equivalent to saying:

((double) 1) / 3.0

This means that 1 gets converted to a double, and 3.0 is automatically a double, so you'll end up doing a floating point division rather than integer division. The same thing would happen with (double) 1 / 3, because the divisor is a double, so even though the dividend is an int, the system realizes that you want to do floating-point division. The compiler doesn't want you to lose precision unless you specifically ask to, so any time either the dividend or the divisor is a double, it will do double division.

On the other hand:

(int) 1 / 3.0

... is the same as saying:

((int) 1) / 3.0

In this case, you're telling the compiler what it already knew: that the divisor (1) is an int. Then you're asking it to divide by a double value (3.0). Since the dividend is a double, it will perform double division.

As you noted, 1/3 will produce zero, because that's how integer division works and both numbers are integers. The same will happen with 1/(int)3.0 because you're telling the compiler to make the 3.0 into an int before the division will occur (as in 1/((int)3.0)).

The final point to keep in mind is that (int) 0.33 will also get converted to 0, because an integer can't hold decimal values in it. So when you say (int)(1.0/3), you're doing double division, but then you're converting the double into an int afterwards, producing 0.

这篇关于对整数和浮点除法的结果应用转换:这里发生了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆