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

Я пробую это простое вычисление в JAVA-приложении:

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

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

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

Если я пишу:

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

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

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

16
задан MC Emperor 27 March 2019 в 12:51
поделиться

4 ответа

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

Попробуйте вместо этого 7,0 / 10 .

61
ответ дан 30 November 2019 в 15:02
поделиться

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

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

или:

1 - 7d / 10
1 - 7 / 10d
1
ответ дан 30 November 2019 в 15:02
поделиться

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

Вы ожидаете деления с плавающей запятой. Любая из следующих оценок будет соответствовать вашим ожиданиям:

7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
24
ответ дан 30 November 2019 в 15:02
поделиться

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

Эта функция используется в каждом уважаемом языке программирования со времен Фортрана (или раньше) - должен признаться, что когда-то я был программистом на перфокартах 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

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

9
ответ дан 30 November 2019 в 15:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: