Módulo:Extenso/Cardinal

Origem: Wikipédia, a enciclopédia livre.
Documentação do módulo[ver] [editar] [histórico] [purgar]

Descrição[editar código-fonte]

Este módulo possibilita processar um valor de entrada (um número inteiro) de modo a devolver o valor por extenso. Pode tanto ser invocado diretamente quanto ser usado por outros módulos.

Uso[editar código-fonte]

  • {{#invoke:Extenso/Cardinal|extenso|<valor>|<flexão de genero>}}

Exemplos[editar código-fonte]

  • {{#invoke:Extenso/Cardinal|extenso|202|m}} → duzentos e dois
  • {{#invoke:Extenso/Cardinal|extenso|202}} → duzentos e dois
  • {{#invoke:Extenso/Cardinal|extenso|202|f}} → duzentas e duas
  • {{#invoke:Extenso/Cardinal|extenso|999999999999999|f}} → novecentas e noventa e nove trilhões novecentas e noventa e nove bilhões novecentas e noventa e nove milhões novecentas e noventa e nove mil novecentas e noventa e nove

Cabeçalho de TemplateData

As informações a seguir (editar) são definidas com TemplateData. Isso possibilita o seu uso pelo Editor Visual e por outras ferramentas.

Escreve o número inteiro por extenso

Parâmetros da predefinição[Editar dados da predefinição]

Esta predefinição prefere a formatação em linha dos parâmetros.

ParâmetroDescriçãoTipoEstado
11

valor a ser escrito por extenso

Exemplo
1102
Númeroobrigatório
22

flexão de gênero a ser aplicada ao número por extenso

Padrão
"f" ou "m", para flexão no feminino e no masculino, respectivamente
Exemplo
f
Valor automático
m
Desconhecidorecomendado

Testes unitários[editar código-fonte]

Todos os testes passaram.

test_module
Texto Esperado Atual
Sim {{#invoke:Extenso/Cardinal|extenso|1|m}} um um
Sim {{#invoke:Extenso/Cardinal|extenso|1|f}} uma uma
Sim {{#invoke:Extenso/Cardinal|extenso|1232|m}} mil duzentos e trinta e dois mil duzentos e trinta e dois
Sim {{#invoke:Extenso/Cardinal|extenso|1232|f}} mil duzentas e trinta e duas mil duzentas e trinta e duas
Sim {{#invoke:Extenso/Cardinal|extenso|1232}} mil duzentos e trinta e dois mil duzentos e trinta e dois
Sim {{#invoke:Extenso/Cardinal|extenso|999999999999999}} novecentos e noventa e nove trilhões novecentos e noventa e nove bilhões novecentos e noventa e nove milhões novecentos e noventa e nove mil novecentos e noventa e nove novecentos e noventa e nove trilhões novecentos e noventa e nove bilhões novecentos e noventa e nove milhões novecentos e noventa e nove mil novecentos e noventa e nove
Sim {{#invoke:Extenso/Cardinal|extenso|999999999999999|f}} novecentas e noventa e nove trilhões novecentas e noventa e nove bilhões novecentas e noventa e nove milhões novecentas e noventa e nove mil novecentas e noventa e nove novecentas e noventa e nove trilhões novecentas e noventa e nove bilhões novecentas e noventa e nove milhões novecentas e noventa e nove mil novecentas e noventa e nove
Sim {{#invoke:Extenso/Cardinal|extenso|9999999999999999}}
Sim {{#invoke:Extenso/Cardinal|extenso|9999999999999999|f}}


Ver também[editar código-fonte]

local p = {}

-- unidades com flexão de gênero masculina
local unidades = {
	[1] = 'um',
	[2] = 'dois',
	[3] = 'três',
	[4] = 'quatro',
	[5] = 'cinco',
	[6] = 'seis',
	[7] = 'sete',
	[8] = 'oito',
	[9] = 'nove'
}

-- unidades com flexão de gênero feminina
local unidades_f = {
	[1] = 'uma',
	[2] = 'duas',
	[3] = 'três',
	[4] = 'quatro',
	[5] = 'cinco',
	[6] = 'seis',
	[7] = 'sete',
	[8] = 'oito',
	[9] = 'nove'
}

-- dezenas estritamente menores que vinte
local dezenas10a19 = {
	[0] = 'dez',
	[1] = 'onze',
	[2] = 'doze',
	[3] = 'treze',
	[4] = 'quatorze',
	[5] = 'quinze',
	[6] = 'dezesseis',
	[7] = 'dezessete',
	[8] = 'dezoito',
	[9] = 'dezenove'
}

-- dezenas maiores que vinte, são complementadas com " e <unidade>" quando não são inteiramente divisíveis por 10
local dezenas = {
	[2] = 'vinte',
	[3] = 'trinta',
	[4] = 'quarenta',
	[5] = 'cinquenta',
	[6] = 'sessenta',
	[7] = 'setenta',
	[8] = 'oitenta',
	[9] = 'noventa'
}

-- centenas com flexão de gênero masculina. A centena 100 é tratada separadamente.
local centenas = {
	[1] = 'cento',
	[2] = 'duzentos',
	[3] = 'trezentos',
	[4] = 'quatrocentos',
	[5] = 'quinhentos',
	[6] = 'seiscentos',
	[7] = 'setecentos',
	[8] = 'oitocentos',
	[9] = 'novecentos',
}

-- unidades com flexão de gênero feminina
local centenas_f = {
	[1] = 'cento',
	[2] = 'duzentas',
	[3] = 'trezentas',
	[4] = 'quatrocentas',
	[5] = 'quinhentas',
	[6] = 'seiscentas',
	[7] = 'setecentas',
	[8] = 'oitocentas',
	[9] = 'novecentas',
}

-- unidade recebe um valor entre 1 e 9 e devolve o nome desse número
local unidade = function(valor, genero)
	local valor = tonumber(valor)
	if valor == 0 then
		return ''
	else
		if genero == 'f' then
			return unidades_f[valor]
		else
			return unidades[valor]
		end
	end
end

-- dezena recebe um valor entre 1 e 99 e devolve o nome desse número de acordo
-- com o caso em que ele se encaixa
local dezena = function(valor, genero)
	local valor = tonumber(valor)
	if valor == 0 then
		return ''
	elseif valor < 10 then					-- valor = {1,2,3,4,5,6,7,8,9}
		return unidade(valor, genero)
	elseif math.floor(valor/10) == 1 then	-- valor = {10,11,12,13,14,15,16,17,18,19}
		return dezenas10a19[valor%10]
	elseif valor%10 == 0 then				-- valor = {20,30,40,50,60,70,80,90}
		return dezenas[valor/10]
	else									-- valor = {21,22,...,29,31,32,...,98,99}
		return dezenas[math.floor(valor/10)] .. ' e ' .. unidade(valor%10, genero)
	end
end

-- centena recebe um valor entre 1 e 999 e devolve o nome desse número de acordo
-- com o caso em que ele se encaixa
local centena = function(valor, genero)
	local valor = tonumber(valor)
	if valor == 0 then
		return ''
	elseif valor < 100 then					-- valor = {1,2,3,...,97,98,99}
		return ' e ' .. dezena(valor, genero)
	elseif valor == 100 then				-- valor = 100
		return 'cem'
	elseif valor%100 == 0 then				-- valor = {200,300,400,...,800,900}
		if genero == 'f' then
			return centenas_f[valor/100]
		else
			return centenas[valor/100]
		end
	else									-- valor = {201,202,...,299,301,...,998,999}
		if genero == 'f' then
			return centenas_f[math.floor(valor/100)] .. ' e ' .. dezena(valor%100, genero)
		else
			return centenas[math.floor(valor/100)] .. ' e ' .. dezena(valor%100, genero)
		end
	end
end

-- units representa a escala da centena|dezena|unidade tratada.
-- x representa a escala no singular e 2x representa a escala no plural
local units = {
	[1] = '',
	[2] = '',
	[10] = '',
	[20] = '',
	[100] = '',
	[200] = '', -- até 999, os valores não possuem escala com nomenclatura
	[1000] = 'mil',
	[2000] = 'mil',
	[10000] = 'mil',
	[20000] = 'mil',
	[100000] = 'mil',
	[200000] = 'mil', -- todos os valores de 1.000 a 999.999 têm a mesma nomenclatura para a escala
	[1000000] = 'um milhão', -- nomenclatura da escala para valores de 1.000.000 a 1.999.999
	[2000000] = 'milhões',
	[10000000] = 'milhões',
	[20000000] = 'milhões',
	[100000000] = 'milhões',
	[200000000] = 'milhões', -- todos os números de 2.000.000 a 999.999.999 têm a mesma nomenclatura para a escala
	[1000000000] = 'um bilhão', -- nomenclatura da escala para valores de 1.000.000.000 a 1.999.999.999
	[2000000000] = 'bilhões',
	[10000000000] = 'bilhões',
	[20000000000] = 'bilhões',
	[100000000000] = 'bilhões',
	[200000000000] = 'bilhões', -- todos os números de 2.000.000.000 a 999.999.999.999 têm a mesma nomenclatura para a escala
	[1000000000000] = 'um trilhão', -- nomenclatura da escala para valores de 1.000.000.000.000 a 1.999.999.999.999
	[2000000000000] = 'trilhões',
	[10000000000000] = 'trilhões',
	[20000000000000] = 'trilhões',
	[100000000000000] = 'trilhões',
	[200000000000000] = 'trilhões' -- todos os números de 2.000.000.000.000 a 999.999.999.999.999 têm a mesma nomenclatura para a escala
}

-- _unidade recebe um valor, a flexão de gênero de escolha e uma base para resgatar a escala do valor
-- e devolve o nome do número. Serve para as ''unidades'' de qualquer escala registrada.
local _unidade = function(valor, genero, base)
	local valor = tonumber(valor)
	local base = tonumber(base)
	if valor == 0 then
		return ''
	elseif valor < base then
		return require("Módulo:Extenso/Cardinal").main(valor, genero, base/10)
	elseif valor == base then
		return units[base]
	elseif math.floor(valor/base) == 1 then
		return units[base] .. ' ' .. require("Módulo:Extenso/Cardinal").main(valor%base, genero, base/10)
	else
		return unidade(math.floor(valor/base), genero) .. ' ' .. units[2*base].. base ..' ' .. require("Módulo:Extenso/Cardinal").main(valor%base, genero, base/10)
	end
end

-- _dezena recebe um valor, a flexão de gênero de escolha e uma base para resgatar a escala do valor
-- e devolve o nome do número. Serve para as ''dezenas'' de qualquer escala registrada.
local _dezena = function(valor, genero, base)
	local valor = tonumber(valor)
	local base = tonumber(base)
	if valor == 0 then
		return ''
	elseif valor < base then
		return require("Módulo:Extenso/Cardinal").main(valor, genero, base/10)
	elseif (valor%(base/10)) == 0 then
		return dezena(math.floor(10*valor/base),genero) .. ' ' .. units[base]
	else
		return dezena(math.floor(10*valor/base),genero) .. ' ' .. units[2*base] .. ' ' .. require("Módulo:Extenso/Cardinal").main(valor%(base/10), genero, base/10)
	end
end

-- _centena recebe um valor, a flexão de gênero de escolha e uma base para resgatar a escala do valor
-- e devolve o nome do número. Serve para as ''centenas'' de qualquer escala registrada.
local _centena = function(valor, genero, base)
	local valor = tonumber(valor)
	local base = tonumber(base)
	if valor == 0 then
		return ''
	elseif valor < base then
		return require("Módulo:Extenso/Cardinal").main(valor, genero, base/10)
	elseif valor == base then
		return 'cem' .. ' ' .. units[base]
	elseif (valor%(base/100)) == 0 then
		return centena(100*valor/base, genero) .. ' ' .. units[base]
	else
		return centena(math.floor(100*valor/base),genero) .. ' ' .. units[2*base] .. ' ' .. require("Módulo:Extenso/Cardinal").main(valor%(base/100), genero, base/100)
	end
end

-- main é a função principal que determina qual outra subfunção irá ser chamada
-- para resgatar o nome do número. Caso o valor tenha até três dígitos, a função
-- correspondente ao número de dígitos é chamada (unidade = 1, dezena = 2 e centena =3.
-- Nos demais casos, trabalha de forma recursiva para construir o nome do número,
-- usando _unidade, _dezena e/ou _centena.
function p.main(valor, genero, base)
	local valor = tostring(valor)
	local padrao = #valor
	if padrao == 1 then --u
		return unidade(valor, genero)
	elseif padrao == 2 then --d
		return dezena(valor, genero)
	elseif padrao == 3 then --c
		return centena(valor, genero)
	elseif base == 1000 or
	base == 1000000 or
	base == 1000000000 or
	base == 1000000000000 then
		return _unidade(valor, genero, base)
	elseif base == 10000 or
	base == 10000000 or
	base == 10000000000 or
	base == 10000000000000 then
		return _dezena(valor, genero, base)
	else
		return _centena(valor, genero, base)
	end
end

-- extenso recebe os argumentos de chamada pelo usuário ou por outro módulo
-- e devolve o nome do número por extenso. Chamada por 
function p.extenso(frame)
	local valor = tostring(frame.args[1])
	local genero = frame.args[2] or 'm'
	if valor == 0 then
		return 'zero'
	elseif tonumber(valor) >= 10^15 then -- por agora, somente para números estritamente menores que 1 quadrilhão
		return ''
	else
		return require("Módulo:Extenso/Cardinal").main(valor, genero, 10^(#valor-1))
	end
end

function p.extenso_module(valor, genero)
	local valor = tostring(valor)
	local genero = genero or 'm'
	if valor == 0 then
		return 'zero'
	elseif tonumber(valor) >= 10^15 then -- por agora, somente para números estritamente menores que 1 quadrilhão
		return ''
	else
		return require("Módulo:Extenso/Cardinal").main(valor, genero, 10^(#valor-1))
	end
end

return p