Вопрос:

Простое деление в Java - это ошибка или фича?

java division

172779 просмотра

5 ответа

581 Репутация автора

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

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

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

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

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

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

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

Что здесь не так?

Автор: msr Источник Размещён: 26.05.2010 12:29

Ответы (5)


61 плюса

10133 Репутация автора

Решение

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

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

Автор: Xavier Ho Размещён: 26.05.2010 12:30

24 плюса

8960 Репутация автора

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

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

7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
Автор: JustJeff Размещён: 26.05.2010 12:33

1 плюс

7028 Репутация автора

Я считаю буквенные идентификаторы более читабельными и более показательными для разбираемого типа:

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

или же:

1 - 7d / 10
1 - 7 / 10d
Автор: Fred Haslam Размещён: 26.05.2010 01:46

9 плюса

12004 Репутация автора

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

Эта функция использовалась во всех уважаемых языках программирования со времен Фортрана (или ранее) - я должен признаться, что когда-то был программистом перфокарт на Фортране и Коболе.

Например, целочисленное деление 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

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

Автор: Blessed Geek Размещён: 26.05.2010 06:11

0 плюса

146 Репутация автора

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

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

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

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

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

Автор: Felipe Volpato Размещён: 12.01.2017 11:01
Вопросы из категории :
32x32