Java 中的简单除法 - 这是错误还是功能?

发布于 2024-09-03 07:36:22 字数 321 浏览 4 评论 0原文

我正在 Java 应用程序中尝试这个简单的计算:

System.out.println("b=" + (1 - 7 / 10));

显然我希望输出为 b=0.3,但实际上我得到的是 b=1

什么?!为什么会出现这种情况?

如果我写:

System.out.println("b=" + (1 - 0.7));

我会得到正确的结果,即b=0.3

这里出了什么问题?

I'm trying this simple calculation in a Java application:

System.out.println("b=" + (1 - 7 / 10));

Obviously I expect the output to be b=0.3, but I actually get b=1 instead.

What?! Why does this happen?

If I write:

System.out.println("b=" + (1 - 0.7));

I get the right result, which is b=0.3.

What's going wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

策马西风 2024-09-10 07:36:22

您正在使用整数除法。

请尝试使用 7.0/10

You're using integer division.

Try 7.0/10 instead.

岁月静好 2024-09-10 07:36:22

您在表达式 7/10 中使用了整数,并且整数 7 除以整数 10 为零。

您所期望的是浮点除法。以下任何一项都会按照您期望的方式进行评估:

7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10

You've used integers in the expression 7/10, and integer 7 divided by integer 10 is zero.

What you're expecting is floating point division. Any of the following would evaluate the way you expected:

7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
月竹挽风 2024-09-10 07:36:22

请不要将此视为问题的答案。它不是,而是与利用 int 和 float 差异相关的建议。我会把它放在评论下,除非答案框允许我格式化这个评论。

自 Fortran 时代(或更早)以来,此功能已在每种受人尊敬的编程语言中使用 - 我必须承认我曾经是 Fortran 和 Cobol 打孔卡程序员。

例如,整数除法 10/3 产生整数值 3,因为整数无法保存小数残差 0.3333...。

我们(古代程序员)使用此功能的方式之一是循环控制。

假设我们希望打印一个包含 1000 个字符串的数组,但我们希望在每 15 个字符串之后插入一个换行符,以便在该行末尾和下一行开头插入一些漂亮的字符。我们利用这一点,假设整数 k 是该数组中字符串的位置。

int(k/15)*15 == k

仅当 k 能被 15 整除时才成立,即每 15 个单元格出现一次。这类似于我的朋友所说的他祖父的死表每天准确两次。

int(1/15) = 0 -> int(1/15)*15 = 0
int(2/15) = 0 -> int(2/15)*15 = 0
...
int(14/15) = 0 -> int(14/15)*15 = 0
int(15/15) = 1 -> int(15/15)*15 = 15

int(16/15) = 1 -> int(16/15)*15 = 15
int(17/15) = 1 -> int(17/15)*15 = 15
...
int(29/15) = 1 -> int(29/15)*15 = 15
int(30/15) = 2 -> int(30/15)*15 = 30

因此,循环中,

leftPrettyfy();
for(int k=0; k<sa.length; k++){
  print(sa[k]);
  int z = k + 1;
  if ((z/15)*15 == z){
    rightPrettyfy();
    leftPrettyfy();
  }
}

通过在循环中以一种奇特的方式改变 k,我们可以打印一个三角形的打印输出,

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15

这就是为了证明,如果你认为这是一个错误,那么这个“错误”是一个有用的功能我们不想被从迄今为止使用的任何一种语言中删除。

Please do not take this as an answer to the question. It is not, but an advice related to exploiting the difference of int and float. I would have put this under a comment except that the answer box allows me to format this comment.

This feature has been used in every respectable programming language since the days of fortran (or earlier) - I must confess I was once a Fortran and Cobol punch card programmer.

As an example, integer division of 10/3 yields integer value 3 since an integer has no facility to hold fractional residual .3333.. .

One of the ways we (old time ancient programmers) had been using this feature is loop control.

Let's say we wish to print an array of 1000 strings, but we wish to insert a line break after every 15th string, to insert some prettyfying chars at the end of the line and at the beginning of the next line. We exploit this, given that integer k is the position of a string in that array.

int(k/15)*15 == k

is true only when k is divisible by 15, an occurrence at a frequency of every 15th cell. Which is akin to what my friend said about his grandfather's dead watch being accurate twice a day.

int(1/15) = 0 -> int(1/15)*15 = 0
int(2/15) = 0 -> int(2/15)*15 = 0
...
int(14/15) = 0 -> int(14/15)*15 = 0
int(15/15) = 1 -> int(15/15)*15 = 15

int(16/15) = 1 -> int(16/15)*15 = 15
int(17/15) = 1 -> int(17/15)*15 = 15
...
int(29/15) = 1 -> int(29/15)*15 = 15
int(30/15) = 2 -> int(30/15)*15 = 30

Therefore, the loop,

leftPrettyfy();
for(int k=0; k<sa.length; k++){
  print(sa[k]);
  int z = k + 1;
  if ((z/15)*15 == z){
    rightPrettyfy();
    leftPrettyfy();
  }
}

By varying k in a fanciful way in the loop, we could print a triangular printout

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15

That is to demonstrate that, if you consider this a bug, this "bug" is a useful feature that we would not want to be removed from any of the various languages that we have used thus far.

蓝咒 2024-09-10 07:36:22

我发现字母标识符更具可读性并且更能指示已解析的类型:

1 - 7f / 10
1 - 7 / 10f

或:

1 - 7d / 10
1 - 7 / 10d

I find letter identifiers to be more readable and more indicative of parsed type:

1 - 7f / 10
1 - 7 / 10f

or:

1 - 7d / 10
1 - 7 / 10d
深海夜未眠 2024-09-10 07:36:22

就我而言,我这样做:

double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1));

而不是“正确”:

double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1);

注意括号!

In my case I was doing this:

double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1));

Instead of the "correct" :

double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1);

Take attention with the parentheses !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文