let inputNum = document.getElementById("inputNmr");
let inputDeBase = document.getElementById("inputBas");
let inputParaBase = document.getElementById("outputBas");
let resultado = document.getElementById("outputNmr");
let converterBtn = document.getElementById("convertBtn");
/**
* Filtra a entrada com base nas bases de origem e destino. Confere se alguma das bases é 10, se são potências, ou se devem passar por base 10 primeiro.
* @param {number} baseOrigem A base original a ser convertida.
* @param {number} baseDestino A base de destino para a qual o número será convertido.
* @returns {string|boolean} Retorna uma string indicando o tipo de conversão necessária ou false se as bases forem inválidas.
*/
function filtrarEntrada(baseOrigem, baseDestino) {
if (baseOrigem >= 2 && baseOrigem <= 36) {
if (baseOrigem === 10) {
return "origem10";
} else if (baseDestino === 10) {
return "destino10";
} else if (baseDestino === baseOrigem ** Math.log2(baseDestino) / Math.log2(baseOrigem)) {
return "mesmaPotencia";
} else {
return "basesDiferentes";
}
}
return false;
}
/**
* Converte um número de uma base para a base 10.
* @param {string} nmr O número a ser convertido.
* @param {number} baseOrigem A base original do número.
* @returns {number} O número convertido para a base 10.
*/
function paraBase10(nmr, baseOrigem) {
const digitos = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let decimal = 0;
for (const c of nmr.toUpperCase()) {
decimal = decimal * baseOrigem + digitos.indexOf(c);
}
return decimal;
};
/**
* Converte um número da base 10 para outra base.
* @param {number} nmr O número em base 10 a ser convertido.
* @param {number} baseDestino A base para a qual o número será convertido.
* @returns {string} O número convertido para a base de destino.
*/
function deBase10(nmr, baseDestino) {
const digitos = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let decimal = nmr;
let resultado = "";
while (decimal > 0) {
resultado = digitos[decimal % baseDestino] + resultado;
decimal = Math.floor(decimal / baseDestino);
}
return resultado === "" ? "0" : resultado;
};
/**
* Valida se um número é válido na base especificada.
* @param {string} nmr O número a ser validado.
* @param {number} baseOrigem A base na qual o número deve ser validado.
* @returns {boolean} Retorna true se o número for válido na base especificada, caso contrário, retorna false.
*/
function validarNmr(nmr, baseOrigem) {
const digitos = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".slice(0, baseOrigem);
return nmr.length > 0 && [...nmr.toUpperCase()].every(c => digitos.includes(c));
}
/**
* Converte um número entre bases que são potências.
* @param {string} nmr O número a ser convertido.
* @param {number} baseOrigem A base original do número.
* @param {number} baseDestino A base de destino para a qual o número será convertido.
* @returns {string}
*/
function converterPotencia(nmr, baseOrigem, baseDestino) {
const digitos = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const bitsOrigem = Math.round(Math.log2(baseOrigem));
const bitsDestino = Math.round(Math.log2(baseDestino));
let binario = "";
for (const c of nmr.toUpperCase()) {
const bloco = deBase10(paraBase10(c, baseOrigem), 2);
binario += "0".repeat(bitsOrigem - bloco.length) + bloco;
}
const resto = binario.length % bitsDestino;
if (resto !== 0) {
binario = "0".repeat(bitsDestino - resto) + binario;
}
let resultado = "";
for (let i = 0; i < binario.length; i += bitsDestino) {
resultado += digitos[paraBase10(binario.substring(i, i + bitsDestino), 2)];
}
return resultado.replace(/^0+(?=.)/, "");
};
convertBtn.addEventListener("click", function () {
let nmr = inputNum.value;
let baseOrigem = Number(inputDeBase.value);
let baseDestino = Number(inputParaBase.value);
inputNum.setCustomValidity("");
inputDeBase.setCustomValidity("");
inputParaBase.setCustomValidity("");
if (isNaN(baseOrigem) || baseOrigem < 2 || baseOrigem > 36) {
inputDeBase.setCustomValidity("A base deve ser um número entre 2 e 36.");
} else if (isNaN(baseDestino) || baseDestino < 2 || baseDestino > 36) {
inputParaBase.setCustomValidity("A base deve ser um número entre 2 e 36.");
} else if (!validarNmr(nmr, baseOrigem)) {
inputNum.setCustomValidity(`"${nmr}" não é um número válido na base ${baseOrigem}.`);
}
if (!inputDeBase.reportValidity() || !inputParaBase.reportValidity() || !inputNum.reportValidity()) {
resultado.value = "";
return;
}
if (filtrarEntrada(baseOrigem, baseDestino)) {
switch (filtrarEntrada(baseOrigem, baseDestino)) {
case "origem10":
resultado.value = deBase10(nmr, baseDestino);
break;
case "destino10":
resultado.value = paraBase10(nmr, baseOrigem);
break;
case "mesmaPotencia":
resultado.value = converterPotencia(nmr, baseOrigem, baseDestino);
break;
case "basesDiferentes":
resultado.value = deBase10(paraBase10(nmr, baseOrigem), baseDestino);
break;
}
}
});