Лучший способ реализовать условное выражение на основе числового значения (положительное, отрицательное, ноль) - PullRequest
2 голосов
/ 16 января 2020

Есть ли лучший изящный способ реализовать наивный следующий код (diffYear, A и B - цифры):

diffYear = yearA - yearB;

if (diffYear == 0) {
    A = B = 0;  
}
else if (diffYear > 0) {
    A = diffYear * -1;
    B = 0;
}
else if (diffYear < 0) {   // obviously one could only write a simple else, this is for the sake of the example
    A = 0;
    B = diffYear;
}

Ответы [ 7 ]

6 голосов
/ 16 января 2020

Эта реализация хороша.

Есть ли лучший изящный способ реализовать наивный следующий код

Практическое правило: ясно ли, что он делает ? Если да, оставьте его.


Возможна и другая реализация, но вы должны принять во внимание, кто будет читать этот код. Например, в команде / организации, где большинство разработчиков используют математику каждый день, я написал бы что-то вроде следующего, чтобы казаться им более «естественным»:

auto neg(int x) { return x < 0 ? x : 0; }
//...
int const A = neg(yearB - yearA);
int const B = neg(yearA - yearB);
1 голос
/ 16 января 2020

Возможное решение:

template<typename T>
std::pair<T, T> neg_diff(T a, T b) {
    if (a < b)
        return {0, a - b};
    else
        return {b - a, 0};
}

const auto [A, B] = neg_diff(yearA, yearB);
0 голосов
/ 16 января 2020
A = min(yearB - yearA, 0);
B = min(yearA - yearB, 0);
0 голосов
/ 16 января 2020

Поскольку мы не знаем, какие типы участвуют в сравнении, я предпочитаю использовать только <, поскольку это обычно первый, а иногда и единственный оператор сравнения, реализованный в пользовательских классах.

diffYear = yearA - yearB;

if(diffYear < 0) { // negative diff
    A = 0;
    B = diffYear;
} else {           // the rest of the diffs
    A = -diffYear; // was: A = diffYear * -1
    B = 0;                
}
0 голосов
/ 16 января 2020

Другой вариант - использовать мин. И макс. Я не уверен, что это более читабельно в этой ситуации, но в некоторых ситуациях это так.

A = -std::max(diffYear, 0);
B = std::min(diffYear, 0);

(Также обратите внимание, что, как правило, я ожидаю, что переменные будут инициализированы, когда они в исходном коде вы можете инициализировать их 0 и вырезать эти строки из блоков if)

0 голосов
/ 16 января 2020

То, что «лучше» или «более элегантно», несколько субъективно, ИМХО. Однако вы можете уменьшить объем кода, используя (троичный) условный оператор :

diffYear = yearA - yearB;
A = (diffYear < 0) ? 0 : diffYear * -1;
B = (diffYear < 0) ? diffYear : 0;

(Обратите внимание, что, как указано в комментариях , когда diffYear == 0 и A, и B будут установлены на ноль, «автоматически».

0 голосов
/ 16 января 2020

Как отметил @Jarod в комментарии, возможно, вы могли бы просто написать его так:

A = B = 0;  
diffYear = yearA - yearB;
if (diffYear > 0)
    A = diffYear * -1;
else if (diffYear < 0)
    B = diffYear;

обратите внимание на else if(yearA < yearB), просто else неверно, потому что мы удалили первое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...