Я пробую это простое вычисление в JAVA-приложении:
System.out.println("b=" + (1 - 7 / 10));
Очевидно, я ожидаю, что вывод будет b=0.3
, но я на самом деле добираюсь b=1
вместо этого.
Что?! Почему это происходит?
Если я пишу:
System.out.println("b=" + (1 - 0.7));
Я получаю правильный результат, который является b=0.3
.
Что идет не так, как надо здесь?
Вы используете целочисленное деление.
Попробуйте вместо этого 7,0 / 10
.
Я нахожу буквенные идентификаторы более читаемыми и более указывающими на разобранный тип:
1 - 7f / 10
1 - 7 / 10f
или:
1 - 7d / 10
1 - 7 / 10d
Вы использовали целые числа в выражении 7/10, а целое число 7, разделенное на целое число 10, равно нулю.
Вы ожидаете деления с плавающей запятой. Любая из следующих оценок будет соответствовать вашим ожиданиям:
7.0 / 10
7 / 10.0
7.0 / 10.0
7 / (double) 10
Пожалуйста, не воспринимайте это как ответ на вопрос. Это не так, это совет, связанный с использованием разницы между 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
То есть продемонстрировать, что, если считать это багом, то этот "баг" - полезная функция, которую мы не хотели бы удалять ни из одного из различных языков, которые мы использовали до сих пор.