Ir para conteúdo
Fórum Script Brasil
  • 0

Desafio - Números Hexadecimais


Durub

Pergunta

Olá galera do fórum do C/C++.

Venho propor um desafio para vocês.

Objetivo:

Criar uma função que passe uma variável do tipo unsigned short (16 bits) para sua representação em hexadecimal, em uma string.

Regras:

  • Não é permitido usar QUALQUER função da biblioteca padrão ou de bibliotecas externas (a única exceção é o malloc da stdlib.h).
  • Você deve alocar a string com malloc, como visto no código postado
  • A representação deve ser exatamente idêntica ao printf do unsigned short utilizando "%0#6x".
  • É necessário enviar a sua função por PM
  • Só pode mandar 1 (uma) função, logo pensem (na verdade, testem!) bem antes de mandarem o que vocês desenvolveram
  • As "entregas" vão até o dia 14/02/2009, quando anunciarei um vencedor
Sua função será testada com o seguinte código:

#include <stdio.h>
#include <stdlib.h>

char *returnHex(unsigned short val);

int main(void) {
    unsigned short input;
    char *string;

    scanf("%hu", &input);
    string = returnHex(input);
    printf("%0#6x - %s", input, string);
    free(string);

    return 0;
}

A avaliação será composta dos seguintes itens:

  • Optimização (Velocidade)
  • Segurança
  • Legibilidade
Notem que este desafio não tem nenhuma relação com o fórum do ScriptBrasil. Não há qualquer tipo de premiação.

Abraços.

Link para o comentário
Compartilhar em outros sites

17 respostass a esta questão

Posts Recomendados

  • 0
Se não entender do assunto, pesquise! Este é o propósito dos desafios.

Eu achei que poucos participariam por não saber fazer conversões, não entender de bases numéricas etc. Mas, como você disse, Durub, basta pesquisar. É uma teoria simples, não é complexo. Basta uma pesquisa no Google, e aparecem diversas páginas sobre o assunto.

http://pt.wikipedia.org/wiki/Convers%C3%A3...e_num%C3%A9rica

http://profdrico.sites.uol.com.br/mudabase.html

http://pt.wikipedia.org/wiki/Sistema_bin%C...atem%C3%A1tica)

O último link fala sobre binários. Mas, se entender o que é uma base numérica, pode-se converter para qualquer base. Pode brincar com qualquer base, de 2 a 36. Por que 36? Estude bases, e entenderá. ;)

Link para o comentário
Compartilhar em outros sites

  • 0

Estou dentro! Já está enviada.

Sugeri meu desafio para o Durub por PM, quem sabe não podemos começar uma série de desafios...

Boa sorte,

Até mais!

Edit-> Bom, pelo menos eu acredito ter enviado, não apareceu na minha "Sent Items", se não recebeu, Durub, me avise!

Editado por == Douplus ==
Link para o comentário
Compartilhar em outros sites

  • 0
Edit-> Bom, pelo menos eu acredito ter enviado, não apareceu na minha "Sent Items", se não recebeu, Durub, me avise!

Para aparecer em "Sent Items" é necessário que, ao enviar a mensagem, você marque a opção Adicionar uma cópia desta mensagem para minha caixa de itens enviados

Estou aprendendo C++ a algum tempo (deve ter +/- 1 mês)

Não tenho muita experiência não, mas já dá pra fazer uns aplicativos básicos...

Vou participar desse torneio !

Começarei a criar o programa e daqui a uns dias eu envio^^

Link para o comentário
Compartilhar em outros sites

  • 0

Meu script já está pronto !

Está funcionando corretamente, mas tenho uma dúvida...

O script deverá retornar o valor exatamente com o printf retorna (maiúsculas, formato, etc.) ?

Ex.:

Ao digitar 15 para a conversão o conteúdo mostrado poderá ser:

0x000f - F
Ou:
0x000f - 000F
Ou:
0x000f - 000f
Ou deverá, obrigatoriamente, ser:
0x000f - 0x000f

Atualmente o meu script retornaria 000f

Seria fácil transformá-lo para mostrar 0x000f, mas isso gastaria 2 bytes a mais de memória...

Posso deixar assim ou devo modificar ?

Aguardo resposta

Link para o comentário
Compartilhar em outros sites

  • 0

A pergunta não foi pra mim, mas como diz aquele sujeito do futebol: a regra é clara. Na mensagem do colega que propôs o desafio está escrito "A representação deve ser exatamente idêntica ao printf do unsigned short utilizando "%0#6x".". Logo, deduz-se que se a saída do printf for, por exemplo, 0x1a2b, sua função também deverá produzir 0x1a2b.

Link para o comentário
Compartilhar em outros sites

  • 0

Galera, estou fechando o desafio antecipadamente devido a problemas pessoais.

Enquanto estava fazendo o benchmark, notei que o maior problema da performance era o malloc, já que alocação de memória é uma tarefa lenta.

Então fiz uma modificação no código de testes:

#include <stdio.h>
#include <stdlib.h>

char *returnHex(char*, unsigned short val);

int main(void) {
    unsigned short input;
    char *string = malloc(7);

    scanf("%hu", &input);
    returnHex(string, input);
    printf("%0#6x - %s", input, string);
    free(string);

    return 0;
}

O resultado do benchmark:

Ambiente de testes: Windows

Compilador: MinGW (optimização desligada)

Processador: Intel Pentium 4 2.40 Ghz

Nota: A ordem de testes não segue nenhum padrão

durub.exe:

Input: 32768

Output: 0x8000 - 0x8000

Número de execuções: 1000000 vezes

Tempo: 31 ms

maligno.exe:

Input: 32768

Output: 0x8000 - 0x8000

Número de execuções: 1000000 vezes

Tempo: 62 ms

jonathan.exe:

Input: 32768

Output: 0x8000 - 0x8000

Número de execuções: 1000000 vezes

Tempo: 31 ms

beraldo.exe:

Input: 32768

Output: 0x8000 - 0=:)x (Sim, estava um smile no "terminal")

Número de execuções: 1000000 vezes

Tempo: 1547 ms

douplus.exe:

Input: 32768

Output: 0x8000 - 0x8000

Número de execuções: 1000000 vezes

Tempo: 156 ms

Comentários:

Beraldo, enquanto estava no Ubuntu, notei que o output saía corretamente (sem estar estranho, que nem mostrado no benchmark), porém, quando fui ao Windows, ocorreu-me este problema. Não se assuste com o resultado do benchmark de seu código, já que como ele utilizava um sistema de realocação, não pude fazer a optimização mudando o código de testes.

Jonathan, tive que remover o static char e utilizar um ponteiro para fazer a optimização.

Gostei muito de ver soluções diferentes, conversão de bases, shifts etc.

O pessoal está de parabéns por ter pensado, pesquisado e feito o código.

Não declararei um vencedor, isso fica a critério de vocês.

Postarei o código de todos em um .rar (espero que não se importem).

Abraços!

Desafio_ScriptBrasil_C__.rar

Link para o comentário
Compartilhar em outros sites

  • 0
Beraldo, enquanto estava no Ubuntu, notei que o output saía corretamente (sem estar estranho, que nem mostrado no benchmark), porém, quando fui ao Windows, ocorreu-me este problema. Não se assuste com o resultado do benchmark de seu código, já que como ele utilizava um sistema de realocação, não pude fazer a optimização mudando o código de testes.

Pelo menos o meu código gerou uma saída bem amigável. :lol:

Totalmente user friendly. :P

Achei estranho ver esse smile aí... eu testei o arquivo exe no Wine e a saída foi esta:

0x8000 - 000x

Mas no terminal do Ubuntu - com a versão compilada pelo GCC, claro, não pelo Windows -, o resultado fica correto. :unsure:

Dei preferência à realocação para não ficar restrito a somente 16 bits.

Enfim, parabéns a todos os participantes!

OBS: Ainda estou decifrando o código do Durub. Ainda não sou bom em manipulação de bits... está difícil entender. :lol:

Você poderia ter colocado uns comentários no código, né...? :P :closedeyes:

Link para o comentário
Compartilhar em outros sites

  • 0

Então, é assim:

Por exemplo, 32768:

val = 1000 0000 0000 0000 (32768)

returnString[2] = tabelaHex[val >> 12];

returnString[2] = tabelaHex[0000 0000 0000 1000];

returnString[2] = tabelaHex[8];

returnString[2] = '8';

O resto vai ser shift e and nos zeros, então continua 0.

Outro exemplo, 16438:

val = 0100 0000 0011 0110

returnString[2] = tabelaHex[val >> 12];

returnString[2] = tabelaHex[0000 0000 0000 0100];

returnString[2] = tabelaHex[4];

returnString[2] = '4';

returnString[3] = tabelaHex[(val >> 8) & 0x000f];

returnString[3] = tabelaHex[0000 0000 0100 0000 & 0x000f];

returnString[3] = tabelaHex[0000 0000 0000 0000];

returnString[3] = tabelaHex[0];

returnString[3] = '0';

returnString[4] = tabelaHex[(val >> 4) & 0x000f];

returnString[4] = tabelaHex[0000 0100 0000 0011 & 0x000f];

returnString[4] = tabelaHex[0000 0000 0000 0011];

returnString[4] = tabelaHex[3];

returnString[4] = '3';

returnString[5] = tabelaHex[val & 0x000f];

returnString[5] = tabelaHex[0100 0000 0011 0110 & 0x000f];

returnString[5] = tabelaHex[0000 0000 0000 0110];

returnString[5] = tabelaHex[6];

returnString[5] = '6';

É uma série explicando a mesma atribuição, não várias!

Ficou um pouco confuso, mas se ver pelo "lado certo" dá para entender!

Abraços!

Link para o comentário
Compartilhar em outros sites

  • 0

Hm...

Achei interessante a solução do Durub (apesar de não ter entendido perfeitamente, vou estudar mais !)

Mas ficou uma dúvida:

Como você fez para calcular o tempo de execução do programa ??

Você modificou o código e incrementou um "timer" ou existe algum programa que faça isso ??

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...