Простое разделение на Java - это ошибка или функция?

Я пытаюсь этот простой расчет в приложении Java:

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

Очевидно, я ожидаю, что результат будет b=0.3, но вместо этого я получаю b=1.

Какие?! Почему это происходит?

Если я напишу:

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

Я получаю правильный результат, который является b=0.3.

Что здесь происходит не так?

Ответ 1

Вы используете целочисленное деление.

Попробуйте 7.0/10.

Ответ 2

Вы использовали целые числа в выражении 7/10, а целое число 7, деленное на целое число 10, равно нулю.

То, что вы ожидаете, - это деление с плавающей запятой. Любое из следующего оценило бы, как вы ожидали:

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

Ответ 3

Пожалуйста, не принимайте это как ответ на вопрос. Это не так, но совет, связанный с использованием разности int и float. Я бы поставил это под комментарий, за исключением того, что в поле ответа я могу отформатировать этот комментарий.

Эта функция использовалась на каждом уважаемом языке программирования со времен fortran (или раньше). Должен признаться, что я когда-то был программистом-программистом Fortran и Cobol.

В качестве примера целочисленное деление 10/3 дает целочисленное значение 3, поскольку целое число не имеет возможности удерживать дробное остаточное значение .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

Чтобы продемонстрировать, что если вы считаете это ошибкой, эта "ошибка" является полезной функцией, которую мы бы не хотели удалять с любого из разных языков, которые мы использовали до сих пор.

Ответ 4

Я нахожу буквенные идентификаторы более читабельными и более ориентированными на разобранный тип:

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

или

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

Ответ 5

В моем случае я делал это:

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

Вместо "правильного":

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

Обратите внимание на круглые скобки!