Túnel do Tempo: a função itoa()

Em uma discussão no fórum de Programação em C e C++ do Viva o Linux, seu proponente perguntava acerca da função itoa(), desejoso de compreender seu funcionamento. Julguei interessante transportá-la, com algumas melhorias, para este espaço, até porque aqui posso fazer algo que não posso fazer naquele fórum, que é dar um exemplo explícito da implementação com código fonte em C.

[ Hits: 16.267 ]

Por: Paulo em 14/06/2017 | Blog: http://unixntools.blogspot.com.br/


Alguns conceitos para a implementação da função



A matemática envolvida para recriar itoa() (de preferência tomando mais cuidado com a segurança da implementação) é simples, dependendo apenas de alguns conceitos que, no meu tempo de estudante, se aprendiam no primeiro grau (atualmente chamado de "ensino fundamental").

A primeira coisa a trazer de volta à mente é a diferença entre número e numeral.

Número é uma grandeza matemática, e tem propriedades que são estudadas e usadas pela Aritmética, pelos estudiosos de Teoria dos Números e em outros campos da Matemática. Já um numeral é uma forma qualquer de referir-se a um número ou, de forma mais geral, a ideias de quantidades.

Tomemos um exemplo pare ilustrar essa diferença. A Matemática define um conjunto de números, chamados números naturais, cujo menor elemento é o número com valor zero, e que cujos sucessivos elementos são formados sempre pelo acréscimo de uma unidade ao elemento anterior.

O décimo-sexto elemento desse conjunto, quando disposto em ordem crescente de seus elementos, é sempre o mesmo número, quer eu me refira a ele como "15" (numeral usando algarismos indo-arábicos), "XV" (numeral romano), "quinze" (numeral cardinal em Português), "fifteen" (numeral cardinal em Inglês), "0xF" (notação hexadecimal da linguagem C), "1111" (numeral binário) ou até mesmo "o décimo-sexto elemento do conjunto dos números naturais disposto em ordem crescente" (numeral ordinal em Português, com referência explícita ao conjunto dos números naturais).

No caso de itoa(), o parâmetro inteiro lhe traz a informação de um número, e o papel da função é converter tal número em um numeral, em forma de texto, armazenando os símbolos que o compõem esse texto numa string.

Outro elemento de conhecimento usado por itoa() é o de notação posicional para representação de um número. A notação posicional para numerais depende de um conjunto finito de algarismos, que são símbolos associados a determinados valores absolutos, e da posição que cada algarismo ocupa na representação do numeral, pois isso indica os valores relativos de cada um deles.

O funcionamento dessa notação é dado pelas seguintes premissas:

1) Se o número de algarismos for n, os valores absolutos de cada um deles correspondem aos n primeiros números naturais (por exemplo: se usarmos dez algarismos, o valor do menor deles é zero e o do maior, nove).

2) O valor relativo do algarismo é o produto do seu valor absoluto por um fator associado à posição por ele ocupada no numeral.

3) O fator associado a cada posição cresce exponencialmente da direita para a esquerda: a posição mais à direta tem um fator unitário (um), e a cada posição deslocada mais à esquerda esse fator é multiplicado por n.

4) O valor relativo de cada algarismo usado na composição do numeral é o produto do seu valor absoluto pelo fator da posição que ele ocupa.

5) O valor do número indicado pelo numeral é então a soma de todos os valores relativos da composição do numeral.

6) Cada número corresponde biunivocamente a um possível numeral usando a representação num sistema de numeração posicional com n algarismos.

Assim sendo, quando se usam os algarismos indo-arábicos ("0", "1", "2", "3", "4", "5", "6", "7", "8" e "9"; dez ao todo), o numeral "2505" significa, literalmente, a soma de 2·10³ (valor absoluto dois, deslocado três posições para a esquerda a partir da posição da unidade, que resulta no valor relativo "dois vezes dez vezes dez vezes dez", ou "dois mil") com 5·10² (valor absoluto cinco, deslocado duas posições para a esquerda a partir da posição da unidade, que resulta no valor relativo "cinco vezes dez vezes dez", ou "quinhentos") com 0·10¹ (valor absoluto zero, deslocado uma posição para a esquerda a partir da unidade, que resulta no valor relativo "zero vezes dez", que é zero) com 5·10⁰ (valor absoluto cinco vezes a unidade, já que esta é a posição mais à direita, que resulta o valor relativo "cinco" -- note que pode-se considerar que houve "zero deslocamentos à esquerda", e que dez elevado a zero realmente vale um).

Na pela terceira ou quarta série (correspondentes aos atuais quarto e quinto anos do Ensino Fundamental) se aprendia somente a notação posicional usando os dez algarismos indo-arábicos. Entretanto, é bom notar que as premissas acima enunciadas falam sobre uma quantidade de algarismos n qualquer, desde que n seja maior que ou igual a dois.

Lá pela sétima ou oitava séries (atuais oitavo ou nono anos), a gente aprendia sobre outros sistemas de numeração e sobre mudanças de bases de numeração. Não raramente os exercícios envolviam um conjunto de símbolos cujos algarismos eram "bolinha", "quadradinho", "triangulinho" e "cruzinha", ou coisa equivalente. Eram comuns exercícios do tipo "Num sistema de numeração cujos algarismos são, em ordem crescente, '@', '#', '$', '%' e '&', qual o valor do numeral '%@&&$#'?" ou "Qual a representação do valor numérico cento e vinte e nove num sistema de numeração cujos algarismos são, em ordem crescente, 'A', 'B', 'C' e 'D'?".

É interessante notar que itoa() é essencialmente uma implementação da solução do segundo exercício.

Página anterior     Próxima página

Páginas do artigo
   1. Apresentação do problema
   2. A implementação da itoa() do antigo Turbo C (e seus problemas)
   3. Alguns conceitos para a implementação da função
   4. Algoritmo para formação do numeral a partir do valor do número
   5. "my_itoa()", uma implementação segura de conversão de número em string
   6. Variações de "my_itoa()"
   7. Conclusão
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Criando programas com suporte a arquivos de configuração com a libConfuse

Programando com uma granada de mão: uma visão da linguagem C

Ponteiros void na linguagem C (parte 2)

Criação e uso de um interpretador de script BrainFuck em C++

Utilizando a biblioteca NCURSES - Parte II

  
Comentários
[1] Comentário enviado por uNclear em 19/06/2017 - 01:55h

ótimo artigo, quando tiver tempo vou fazer alguns testes

[2] Comentário enviado por uilianries em 19/06/2017 - 11:23h

Muito bem detalhado. Parabéns pelo conteúdo, Paulo.

[3] Comentário enviado por Nick-us em 01/03/2019 - 20:08h

Valeu a pena ler e guardar! informação nunca é demais!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts