2010-03-03 2 views
2

Что я здесь делаю неправильно?simple boolean question

Я хочу показать целые числа от 1 до 100, которые делятся на 6 или 7. Это сделано и работает. Следующий шаг, чтобы не отображать любые, которые делятся на обоих ... что не работает в моем цикле (эти числа еще отображения)

for (int i = 1; i < 100; i++) 
    if (i % 6 == 0 || i % 7 == 0 && i % (6 * 7) != 0){ 
     println(i); 
    } 

Спасибо! Joel

+0

Оператор Java Внеочередные: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/Operat ors.html # nutsandbolts-priority –

+0

Прохладный. Благодаря! Я ошибочно отделял три аргумента в моей голове и не думал о скобках ... – Joel

+0

Вы не тот Джоэл, как «http: //www.joelonsoftware.com/', right –

ответ

5

попытаться сделать ваше состояние более явным добавлением (...), например, так:


if (((i % 6 == 0 || i % 7 == 0) && (i % (6 * 7) != 0)) { 
} 

по умолчанию & & имеет приоритет над ||

+1

в общем, никогда не предполагали ничего о порядке оценки или «липкости» логических операторов, всегда добавляйте (...) – radai

+0

отлично. Спасибо, парни! – Joel

3

Недостающие скобки:

for (int i = 1; i < 100; i++) { 
    if ((i % 6 == 0 || i % 7 == 0) && i % (6 * 7) != 0) { 
     println(i); 
    } 
} 
+0

Спасибо, что сделал! – Joel

1
for (int i = 1; i < 100; i++) 
if ((i % 6 == 0 || i % 7 == 0) && !(i % 6 == 0 && i % 7 == 0)){ 
    println(i); 
} 
+1

Это НЕ компилируется! Неправильное положение закрывающейся скобки здесь '(i% 6 == 0 || i% 7) == 0' должно быть' (i% 6 == 0 || i% 7 == 0) ' –

+0

oops, спасибо за что – objects

2

Я бы просто перестать беспокоиться о том, как оценить приоритет, и использовать что-то вроде:

for (int i = 1; i <= 100; i++) { 
    if ((i % 42) == 0) continue; 
    if ((i % 6) == 0) println (i); 
    if ((i % 7) == 0) println (i); 
} 

Я предполагаю, что здесь 1-100 был включающий диапазон, в этом случае вы должны использовать <=, а не <. Это не имеет значения для вашего конкретного случая, поскольку 100 делится ни на 6, ни на 7.

Угадайте, что? Любой достойный оптимизирующий компилятор (включая JIT), вероятно, в конечном итоге будет генерировать тот же код, что и для всех других возможностей. И даже если бы это не так, неважно, если бы вы не называли эту функцию отличной многими раз.

Я думаю, что это чуть-чуть более читаемым, чем:

if (i % 6 == 0 || i % 7 == 0 && i % (6 * 7) != 0) ... 

или, что еще хуже, Lisp, как вещь, которую вы должны будете превратить его, чтобы он работал правильно :-)


Имейте в виду одну возможность - вы можете изменить свой цикл, чтобы сделать его более эффективным (в семь раз), для конкретного случая с 6 и 7, таким образом:

for (int i = 7; i <= 100; i += 7) 
    if ((i % 6) != 0) 
     println (i); 

Это использует сам for цикл, чтобы проверить только кратные 7 и распечатать их, если они не также кратные 6.

2

Вы также можете использовать эксклюзивный или

for (int i = 1; i < 100; i++) { 
     if ((i % 6 == 0)^(i % 7 == 0)) { 
      println(i); 
     } 
    } 

или просто неравные if ((i % 6 == 0) != (i % 7 == 0))
Поскольку исключающее или не используется так часто, я сомневаюсь, что это повысит читаемость кода ...