84 lines
2.6 KiB
JavaScript
84 lines
2.6 KiB
JavaScript
function casasDecimaisFromPrecisao(precisao) {
|
|
if (!Number.isFinite(precisao) || precisao <= 0) return 0
|
|
if (precisao >= 1) return 0
|
|
|
|
const texto = precisao.toString()
|
|
if (texto.includes("e-")) {
|
|
const [, exp] = texto.split("e-")
|
|
const n = Number(exp)
|
|
return Number.isFinite(n) ? n : 0
|
|
}
|
|
const idx = texto.indexOf(".")
|
|
if (idx === -1) return 0
|
|
const dec = texto.slice(idx + 1).replace(/0+$/, "")
|
|
return dec.length
|
|
}
|
|
|
|
function parseNumero(texto) {
|
|
const normalizado = (texto ?? "").trim().replace(/,/g, ".")
|
|
if (!normalizado) return null
|
|
const n = Number(normalizado)
|
|
if (Number.isNaN(n)) return null
|
|
return n
|
|
}
|
|
|
|
function formatarNumero(value, casas) {
|
|
if (value === null || value === undefined) return ""
|
|
if (casas === null) return String(value)
|
|
const fixed = Number(value).toFixed(Math.max(0, casas))
|
|
return fixed.replace(/\./g, ",")
|
|
}
|
|
|
|
function somenteNumeros(texto) {
|
|
return (texto ?? "").replace(/\D+/g, "")
|
|
}
|
|
|
|
function somenteNumerosESeparadorDecimal(texto) {
|
|
const limpo = (texto ?? "").replace(/[^0-9.,]+/g, "")
|
|
const matchSep = limpo.match(/[.,]/)
|
|
if (!matchSep) return limpo
|
|
|
|
const sep = matchSep[0]
|
|
const idx = limpo.indexOf(sep)
|
|
const antesRaw = limpo.slice(0, idx).replace(/[.,]/g, "")
|
|
const depois = limpo.slice(idx + 1).replace(/[.,]/g, "")
|
|
|
|
const antes = antesRaw.length ? antesRaw : "0"
|
|
return `${antes}${sep}${depois}`
|
|
}
|
|
|
|
function valorParcialDecimal(texto) {
|
|
const m = texto.match(/^(\d+)[.,]$/)
|
|
if (!m) return null
|
|
const n = Number(m[1])
|
|
return Number.isNaN(n) ? null : n
|
|
}
|
|
|
|
function simularInput(textoAtual, novoChar, casasDecimais) {
|
|
const texto = textoAtual + novoChar;
|
|
const isInteiro = casasDecimais === 0;
|
|
const isFixedPoint = casasDecimais !== null && casasDecimais > 0;
|
|
|
|
if (isFixedPoint) {
|
|
const digitos = somenteNumeros(texto)
|
|
const baseInt = digitos ? Number(digitos) : 0
|
|
const divisor = 10 ** casasDecimais
|
|
const n = digitos ? baseInt / divisor : null
|
|
return formatarNumero(n, casasDecimais);
|
|
}
|
|
|
|
const base = isInteiro ? somenteNumeros(texto) : somenteNumerosESeparadorDecimal(texto);
|
|
const textoFiltrado = base; // simplificado
|
|
|
|
let out = null;
|
|
if (textoFiltrado) {
|
|
const parcial = isInteiro ? null : valorParcialDecimal(textoFiltrado);
|
|
out = parcial ?? parseNumero(textoFiltrado);
|
|
}
|
|
return formatarNumero(out, casasDecimais);
|
|
}
|
|
|
|
console.log("Com casasDecimais = null (livre)");
|
|
console.log("Digita 1:", simularInput("", "1", null));
|
|
console.log("Digita ,:", simularInput("1", ",", null));
|
|
console.log("Digita 5:", simularInput("1,", "5", null));
|