Java中的简单划分 - 这是一个错误还是一个功能?

msr*_*msr 16 java division

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

System.out.println("b=" + (1 - 7 / 10));
Run Code Online (Sandbox Code Playgroud)

显然我想要b=0.3输出,但这就是我得到的b=1.

什么?!为什么会这样?

如果我做:

System.out.println("b=" + (1 - 0.7));
Run Code Online (Sandbox Code Playgroud)

我得到了正确的结果b=0.3.

这里出了什么问题?

Xav*_* Ho 61

你正在使用整数除法.

试试吧7.0/10.

  • 我要补充一点,这不是一个错误.这是一个功能.`:]` (27认同)
  • 既不是bug也不是功能 - 它是"按设计工作". (10认同)

Jus*_*eff 24

你在表达式7/10中使用了整数,整数7除以整数10是零.

你期待的是浮点除法.以下任何一种都会评估您的预期方式:

7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
Run Code Online (Sandbox Code Playgroud)


Ble*_*eek 9

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

自从fortran(或更早)的日子以来,这个特性已被用于各种可敬的编程语言中 - 我必须承认我曾经是Fortran和Cobol的打卡程序员.

例如,10/3的整数除法产生整数值3,因为整数无法容纳小数残差.3333 ..

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

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

int(k/15)*15 == k
Run Code Online (Sandbox Code Playgroud)

只有当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
Run Code Online (Sandbox Code Playgroud)

因此,循环,

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

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

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15
Run Code Online (Sandbox Code Playgroud)

这是为了证明,如果你认为这是一个错误,这个" 错误 "是一个有用的功能,我们不希望从我们迄今使用的任何语言中删除.

  • FWIW,我在我的盒子上测试了这个(2011年中期2.8 GHz i7 Linux桌面运行JDK 1.6.0_38),并且对于`a` = 1.5亿,超过10次重复,`(a%15 == 0)`平均约为1500毫秒,而对于`(a == 15*(a/15))`约为1400毫秒.因此,除非你已经证明'%`是你的热点,在现代硬件上,我认为你最好不要写你的意思. (2认同)