2015-01-25 4 views
1

Я работаю с кодом, который определяет, год ли високосный год или нет. Это функция, которая у меня есть, какая формула високосного года - лучший вариант?

private boolean leapYear(int year) 
{ 
    boolean t = false; 
    if((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) 
     t = true; 
    return t; 
} 

функция работает нормально, но я afried, что он может иметь некоторые ошибки, Вот почему у меня есть этот другой вариант:

private boolean esBisiesto(int year) 
{ 
    boolean t = false; 
    if((year % 4 == 0)&&(year % 100!=0 ||(year % 100 == 0 && year % 400 == 0))) 
     t = true; 
    return t; 
} 

но я не знаю, какой из них является лучшим вариантом.

+0

Какие даты вы тестируете? Если вы проверяете только даты между 1901 и 2099 годами, тогда будет действовать только 'year% 4 == 0'. Другое условие не срабатывает, если дата не находится за пределами этого диапазона. – cup

+0

@laune: Как неверна вторая форма? Я провел несколько тестов на них обоих, и они оба выглядели правильно. – Makoto

+0

@Makoto Вы можете сразу увидеть, что ** вторая форма ** содержит ** избыточный ** год% 100 == 0, потому что невозможно, чтобы целое число, кратное 400, тоже не кратно 100. Я ошибался, говоря, что вторая форма неверна, но я был прав, когда я цитировал круглые скобки вокруг '||'. Первая форма выражает правило простым способом. – laune

ответ

1

There are no apparent data bugs; оба метода вернут правильное значение для правильного года. Если вас когда-либо беспокоит наличие ошибок в вашем коде, проверьте это! Это самый быстрый способ получить обратную связь по методу, который вы хотите быть уверенным, и если вы проверите тест вокруг, вы сможете убедиться, что вы случайно не нарушаете этот метод.

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

Начнем с наизнанку. Кроме того, обратите внимание, что я просто сократил оператор return, чтобы мы не выполняли ненужное присваивание переменной.

boolean esBisiesto(int year) { 
    return year % 4 == 0 && (year % 100 != 0 || (year % 100 == 0 && year % 400 == 0)); 
} 

Выражение (year % 100 != 0 || (year % 100 == 0 && year % 400 == 0)) можно переписать в виде year % 100 != 0 || year % 400 == 0, потому что во второй or ветви, подразумевается, что year % 100 == 0 (или мы должны были замкнуть первой ветви).

2

Версия 1 верна. На самом деле нет никакой необходимости так много скобок:

boolean leapYear = year % 4 == 0 && year % 100 != 0 || year % 400 == 0; 

будет работать нормально

1

Если вы не желая изобретать велосипед, java.util.GregorianCalendar уже есть метод полезности: isLeapYear(year)

for (int year = 1997; year <= 2015; year++) { 
    System.out.println(String.format("%d %b", year, new GregorianCalendar().isLeapYear(year))); 
} 
Смежные вопросы