javascript - Testando se um valor é ímpar ou par
Decidi criar funções simples isEven e isOdd com um algoritmo muito simples:
function isEven(n) {
n = Number(n);
return n === 0 || !!(n && !(n%2));
}
function isOdd(n) {
return isEven(Number(n) + 1);
}
Isso é OK se n estiver com certos parâmetros, mas falha em muitos cenários. Então, eu decidi criar funções robustas que fornecem resultados corretos para o maior número possível de cenários, de modo que apenas inteiros dentro dos limites dos números do JavaScript sejam testados, tudo o mais retorna falso (incluindo + e - infinito). Note que zero é par.
// Returns true if:
//
// n is an integer that is evenly divisible by 2
//
// Zero (+/-0) is even
// Returns false if n is not an integer, not even or NaN
// Guard against empty string
(function (global) {
function basicTests(n) {
// Deal with empty string
if (n === '')
return false;
// Convert n to Number (may set to NaN)
n = Number(n);
// Deal with NaN
if (isNaN(n))
return false;
// Deal with infinity -
if (n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY)
return false;
// Return n as a number
return n;
}
function isEven(n) {
// Do basic tests
if (basicTests(n) === false)
return false;
// Convert to Number and proceed
n = Number(n);
// Return true/false
return n === 0 || !!(n && !(n%2));
}
global.isEven = isEven;
// Returns true if n is an integer and (n+1) is even
// Returns false if n is not an integer or (n+1) is not even
// Empty string evaluates to zero so returns false (zero is even)
function isOdd(n) {
// Do basic tests
if (basicTests(n) === false)
return false;
// Return true/false
return n === 0 || !!(n && (n%2));
}
global.isOdd = isOdd;
}(this));
Alguém consegue ver algum problema com o acima? Existe uma versão melhor (ou seja, mais precisa, rápida ou mais concisa sem ser obscura)?
Existem várias postagens relacionadas a outros idiomas, mas não consigo encontrar uma versão definitiva para ECMAScript.
Resposta #1
Use módulo:
function isEven(n) {
return n % 2 == 0;
}
function isOdd(n) {
return Math.abs(n % 2) == 1;
}
Você pode verificar que qualquer valor em Javascript pode ser convertido para um número com:
Number.isFinite(parseFloat(n))
Essa verificação deve, de preferência, ser feita fora das funções isEven e isOdd, para que você não precise duplicar o tratamento de erros em ambas as funções.
Resposta #2
Eu prefiro usar um teste de bit:
if(i & 1)
{
// ODD
}
else
{
// EVEN
}
Isso testa se o primeiro bit está ligado, o que significa um número ímpar.
