[c++] programa para converter numeros

PTBlueDragon

Power Member
um programa que converta números positivos introduzidos pelo utilizador em numeração binária, hexadecimal e romana. Crie as funções que entender adequadas.

será k alguem consegue?
é urgente
 
Boas!

Uma das regras não escritas deste fórum é que não se dá trabalho, ajudamos com todo o gosto se soubermos e pudermos, agora fazer ninguém te vai fazer! Tenta por ti mesmo, se tiveres dúvida no algoritmo ou quiseres dicas para te ajudar na implementação o pessoal ainda te ajuda ;)

abraços, HecKel

PS -> Pesquisa antes como se fazem conversões e vais ver que não é nada do outro mundo :)
 
Tu consegues. :)

Usa o google, wikipedia, aprende a converter números de base 10 para outras bases, e quanto à numeração romana, bem, é a mesma coisa, apenas tens que pensar um pouco mais, o que não deve ser problema para uma pessoa que sabe ir a um fórum de informática e colocar um post.

Boa sorte.
 
Estava mesmo a estudar c++, por isso até deu jeito que fez-me relembrar isto:


#include <iostream>
using namespace std;

int main()
{
int aux;
cout << "Introduza o valor em decimal:" << endl;
cin >> aux;
cout << " valor em hexadecimal : "<< hex << aux << endl;

return 0;
}

Só faz para hexa, nao querias tudo feito pois não :P
 
Isso é uma beca à frente para mim :p Qual é o objectivo de pedirem um programa para fazer conversões se nem as contas fazes?

Dando uma ajuda nas pesquisas:
http://en.wikipedia.org/wiki/Hexadecimal#Converting_from_other_bases
http://pt.wikipedia.org/wiki/Sistema_hexadecimal
http://www.the-eggman.com/seminars/about_hex.html
http://www.novaroma.org/via_romana/numbers.html
http://en.wikipedia.org/wiki/Roman_numerals
http://met.open.ac.uk/group/jwl/info/rom_num.htm
http://www.gwydir.demon.co.uk/jo/roman/number.htm

Nem me dei ao trabalho por procurar por binário..., é tão trivial que dá medo :p, já agora..., usa uma variável do tipo "String" para guardares os resultados das conversões..., senão vais ter problemas :)

abraços, HecKel
 
ScOrpion-boy disse:
:x2: Por isso é que dizem que c++ é muito poderosa ;) :victory:
ya ya, de facto isso faz-te a papinha toda..., mas suponho que o pretendido seja mesmo ele estudar a forma de converter os numeros..., tal como o Alph referiu a unica que é capaz de trazer um pouco mais de complicação é decimal para romana..., de resto são apenas divisões :)

abraços, HecKel
 
para binario e hexa é mt facil (divisoes sucessivas) .. para numeraçao romana ja n é tao simples... mas tmb nd doutro mundo.

caso percebas de scheme aqui tens 1 soluçao (google is a nice friend ;)):

Código:
; decimal->roman : integer -> string
;   format the integer num using roman numerals
(define (decimal->roman num)
  (let ((decimal-numbers (list 1000 900 500 400 100 90 50 40 10 9 5 4 1))
        (roman-numbers   (list "M" "CM" "D" "CD" "C" "XC" "L" 
                               "XL" "X" "IX" "V" "IV" "I")))
    (decimal->roman-aux num "" decimal-numbers roman-numbers)))

; decimal->roman-aux : integer string (list number) (list string) -> string
;   append the numbers num formatted as roman numerals to the string s,
;   using the roman numerals in roman-numbers with corresponding
;   decimal values in decimal-values
(define (decimal->roman-aux num s decimal-numbers roman-numbers)
  (if (null? decimal-numbers)
      s
      (if (>= num (car decimal-numbers))
          (decimal->roman-aux (- num (car decimal-numbers)) 
                              (string-append s (car roman-numbers)) 
                              decimal-numbers roman-numbers)
          (decimal->roman-aux num s 
                              (cdr decimal-numbers) (cdr roman-numbers)))))

podia-te passar isto pa c mas assim n tinhas qse trabalho nenhum a passar dps pa c++ :P
 
Fiz um pugraminha para passar para romanos!
Só funciona de 0 a 99 :002:

#include <iostream>
#include <string>
using namespace std;

string num1(int x)
{
string a;
x%=10;
switch (x)
{
case 0 : a=" ";break;
case 1 : a="I";break;
case 2 : a="II";break;
case 3 : a="III";break;
case 4 : a="IV";break;
case 5 : a="V";break;
case 6 : a="VI";break;
case 7 : a="VII";break;
case 8 : a="VIII";break;
case 9 : a="IX";break;

}
return a;
}

string num2(int x)
{

string a;
x/=10;
switch (x)
{
case 0 : a=" ";break;
case 1 : a="X";break;
case 2 : a="XX";break;
case 3 : a="XXX";break;
case 4 : a="XL";break;
case 5 : a="L";break;
case 6 : a="LX";break;
case 7 : a="LXX";break;
case 8 : a="LXXX";break;
case 9 : a="XC";break;
}
return a;
}

int main()
{
int x;
cout << "*********************************"<<endl;
cout << "** TECHZONPT **" << endl;
cout << "** **" << endl;
cout << "*********************************"<< endl;

do
{
cin >> x;

if(x>10)
{
cout << num2(x)<< num1(x)<< endl;
}
else
{
cout<<num1(x)<<endl;
}
}
while(1);
return 0;
}

Edit:
Retirei a ideia deste site:
http://home.hiwaay.net/~lkseitz/math/roman/
 
Última edição:
Bem..., e não notas nenhum padrão na numeração romana? :p Dava para simplificares isso BEM MAIS e alargares facilmente para mil..., ou mais...

A numeração romana funciona segundo vários critérios (agrupamentos)
- Padrão dos multiplos de 5 (unidade 1)
- Padrão dos multiplos de 10 (unidade 10)
- Padrão dos multiplos de 50 (5*10) (unidade 10)
- Padrão dos multiplos de 100 (10*10) (unidade 100)
(blablabla)

Depois sabes que consoante a unidade escolhida (referido entre parentesis) encontras um outro padrão:
- 1ª-3ª unidades incrementa-se apenas o simbolo
- 4ª unidade simbolo da unidade + simbolo do próximo multiplo de 5

Nada como decompor os números e facilitares as contas..., usa divisões..., restos..., e afins..., com isso consegues facilmente detectar qual o padrão que vais aplicar, depois só tens de concatenar as strings :)

Este algoritmo é "ligeiramente" atrofiante de perceber..., aparentemente resulta, nunca o estudei estou agora a analizar o caso pela primeira vez, simplesmente não gosto muito de alguns cases que usas para poupares calculos..., por vezes os cáculos mais complexos são os melhores na extensibilidade do programa (nem sempre....), e da forma como estás a fazer sempre que quisesses "extender" a "banda" do teu programa terias de alterar o código..., recompilar..., blá blá blá...., excelente para quem faz um software e já está a contar com o guito que vai cobrar no suporte :x2:

abraços, HecKel
 
DE facto a solução do scorpio é "à preguiçoso"... Existe de facto um padrão como disse o heckel. Há uns anos, argh... há muitos anos... fiz umas funções desse tipo lembro-me que na altura ainda deram algum trabalho.
Divirtam-se.

Código:
/* to_roman.c -- convert a value to a roman string */

/* $Id$ */
/* Carlos Duarte, 950816/980104 */

/*
 * int to_roman(unsigned int rval, char *str, size_t max);
 *         converts `rval', into a string that represents that value in
 *         roman, and write results on `str', but no more than `max' chars
 *         (including the final \0)
 * 
 * The above is all that is necessary to use this file: just compile it,
 * with no special options, to get code for `to_roman()' function
 * 
 * --
 * 
 * But, to go further:
 * 
 * . there are 3 != implementations, each can be obtained by defining ROMAN
 *   to a number (1 for first, 2 for second and 3 for third)
 * 
 * . the first is the default
 * 
 * . also, a test is provided, define -DTEST to get it
 * 
 * . and a demo, which is obtained with -DDEMO
 * 
 * . and finally, a PROF, that measure time performance of the three routines, 
 *   this is obtained with -DPROF.
 *   Also, with -DPROF, also -DTOP_ROMAN will be recognized as 1 .. TOP_ROMAN
 *   values to convert
 * 
 * --
 * 
 * As for the algorithms: the first, use a table with all possible
 * combinations of roman digits or pairs, and keep removing
 * the biggest value, while it can. This is the faster.
 * 
 * The other two, use the same algorithm, but implemented
 * on a diferent way. The roman value, is parsed from lowest
 * to greatest digit (as oposed above). But, while `to_roman2'
 * does a base of 10, then base of 5 way of convert, `to_roman3'
 * use only a base of 10 parser and convert all possible
 * 10 digits directly. `to_roman2' use symmetry to convert 6-9
 * into 1-5, and then convert only 1-5. 
 * 
 * As for time speed, #1 > #3 > #2. 
 */

#ifndef ROMAN
#define ROMAN 1
#endif

#if ROMAN == 1
/*=======================================================================*/

#include <stddef.h>

const static struct roman_table {
        int val; 
        char *sym; 
} r_tab[] = { 
        { 1000,  "M" }, 
        {  900, "CM" }, 
        {  500,  "D" }, 
        {  400, "CD" }, 
        {  100,  "C" }, 
        {   90, "XC" }, 
        {   50,  "L" }, 
        {   40, "XL" }, 
        {   10,  "X" }, 
        {    9, "IX" }, 
        {    5,  "V" }, 
        {    4, "IV" }, 
        {    1,  "I" }
}; 

int 
to_roman(unsigned int rval, char *str, size_t max)
{
        const struct roman_table *t; 
        char *s, *top; 

        if (max < 3)
                return 0; 

        s = str; 
        top = s+(max-3);        /* save space for 3 chars write */
        t = r_tab; 
        while (rval) {
                while (rval >= t->val) {
                        if (s > top)
                                return (*s=0)-1; 
                                
                        rval -= t->val; 
                        *s++ = t->sym[0]; 
                        if (t->sym[1])
                                *s++ = t->sym[1]; 
                }
                t++; 
        }
        *s = 0; 
        return s-str; 
}

#endif /* ROMAN == 1 */


#if ROMAN == 2
/*=======================================================================*/

#include <stddef.h>

static const char rr_dig[] = "IVXLCDM";

int 
to_roman(unsigned int rval, char *str, size_t max)
{
        const char *r, *top; 
        char *s; 
        int dig; 

        if (max < 5)
                return 0; 
        r = rr_dig; 
        s = str; 
        top = s+(max-5);        /* ensure space for 5 chars write */
        while (rval) {
                if (s > top)
                        return (*s=0)-1; 

                dig = rval%10; 
                rval /= 10; 
                if (dig != 0) {
                        int c0, c1, c2; 
                        c1 = r[0]; 
                        c0 = 0; 
                        c2 = r[1]; 
                        if (dig > 5) {
                                dig -= 5; 
                                c0 = r[1]; 
                                c2 = r[2]; 
                        }
                        switch (dig) {
                        case 3: *s++ = c1; 
                        case 2: *s++ = c1; 
                        case 1: *s++ = c1; if (c0) *s++ = c0; break; 
                        case 4: *s++ = c2; *s++ = c1; break; 
                        case 5: *s++ = c2; break; 
                        }
                }
                if (*++r == 0 || *++r == 0 || r[1] == 0) {
                        top += 3;       /* ensure space for 2 (5-3) chars */
                        if (rval) do {
                                if (s > top)
                                        return (*s=0)-1; 
                                *s++ = 'M'; 
                        } while (--rval > 0); 
                }
        }
        *s = 0; 
        /* reverse str */
        {char*t=s-1;char*tt=str;while(t>tt){int c= *t;*t-- = *tt;*tt++ =c;}}
        return s-str; 
}

#endif /* ROMAN == 2 */

#if ROMAN == 3
/*=======================================================================*/

#include <stddef.h>

static const char r_dig[] = "IVXLCDM";

int 
to_roman(unsigned int rval, char *str, size_t max)
{
        const char *r, *top; 
        char *s; 
        int dig; 

        if (max < 5)
                return 0; 
        r = r_dig; 
        s = str; 
        top = s+(max-5);        /* ensure space for 5 chars write */
        while (rval) {
                if (s > top)
                        return (*s=0)-1; 

                dig = rval%10; 
                rval /= 10; 
                switch (dig) {
                default: 
                case 0: break; 
                case 3: *s++ = r[0]; 
                case 2: *s++ = r[0]; 
                case 1: *s++ = r[0]; break; 
                case 4: *s++ = r[1]; *s++ = r[0]; break; 
                case 5: *s++ = r[1]; break; 
                case 8: *s++ = r[0]; 
                case 7: *s++ = r[0]; 
                case 6: *s++ = r[0]; *s++ = r[1]; break; 
                case 9: *s++ = r[2]; *s++ = r[0]; break; 
                }
                if (*++r == 0 || *++r == 0 || r[1] == 0) {
                        top += 3;       /* ensure space for 2 (5-3) chars */
                        if (rval) do {
                                if (s > top)
                                        return (*s=0)-1; 
                                *s++ = 'M'; 
                        } while (--rval > 0); 
                }
        }
        *s = 0; 
        /* reverse str */
        {char*t=s-1;char*tt=str;while(t>tt){int c= *t;*t-- = *tt;*tt++ =c;}}
        return s-str; 
}

#endif /* ROMAN == 3 */
Código:
/* fr_roman.c -- from roman string to integer */

/* $Id$ */
/* Carlos Duarte, 971226 */


/* 
 * int fr_roman(const char *str);
 *      
 *      converts `str', that should represent a valid 
 *      roman number, to its value
 * 
 *      returns the value, or -1, in case the string
 *      is not valid
 */


int
fr_roman(const char *str)
{
        int sum, v, v0; 

        sum = 0; 
        v0 = 1001; 
        for (;;) {
                switch (str[0]) {
                case 'M': v = 1000; break; 
                case 'D': v = 500; break; 
                case 'C': switch (str[1]) {
                        case 'M': v = 900; str++; break; 
                        case 'D': v = 400; str++; break; 
                        default:  v = 100; break; 
                        }
                        break; 
                case 'L': v = 50; break; 
                case 'X': switch (str[1]) {
                        case 'C': v = 90; str++; break; 
                        case 'L': v = 40; str++; break; 
                        default:  v = 10; break; 
                        }
                        break; 
                case 'V': v = 5; break; 
                case 'I': switch (str[1]) {
                        case 'X': v = 9; str++; break; 
                        case 'V': v = 4; str++; break; 
                        default:  v = 1; break; 
                        }
                        break; 
                case 0:  return sum; 
                default: return -1; 
                }
                if (v > v0) 
                        break; 
                v0 = v; 
                sum += v; 
                ++str; 
        }
        return -1; 
}
 
Aqui está uma possível resolução, espero que ajude, dá para converter todas as bases da binaria à hexadecimal


#include <stdio.h>
int main(void){
int n,b,q,r,base[10]={0},i=0,z,j=0;
printf("Qual o número na base decimal?\n");
scanf (" %d",&n);
printf("Qual a base para que quer transformar o número?\n");
scanf (" %d",&b);
q=n;
while(q!=0){
r=(q%b);
q=(q/b);
if(r==10) r='A';
else if (r==11) r='B';
else if (r==12) r='C';
else if (r==13) r='D';
else if (r==14) r='E';
else if (r==15) r='F';
base=r;
i++;
j++;
}
for (i=0;i<(j/2);i++){
z=base;
base=base[j-i-1];
base[j-i-1]=z;
}
printf("O número %d em base decimal é igual a ",n);
for(i=0;i<j;i++) {
if (base<9 && base>0) printf(" %d ", base);
else printf(" %c ", base);
}
printf(" na base %d\n",b);
return 0;
}
 
Back
Topo