Konvertierungsprogramm in C

Das Forum fĂĽr Programmierer und Systemadmins. Von Shell-, Perl- und PHP-Scripts bis zur objektorientierten Programmierung mit C++.

Beitragvon moonangel » Mi 11 Okt, 2006 11:48

:nixkapier:

nochmal ^^:

Der Benutzer gibt eine Zahl und deren Basis ein.
Dann gibt er die Basis ein in der er diese Zahl haben möchte.
Das program mwandelt dann die eingegeben zahl in die
basis um in die er sie haben möchte.

und das einzige was ich hatte war lediglich ein programm
das mir eine Dezimalzahl in eine beliebige (die ich natĂĽrlich
vom Benutzer eingeben lasse) basis umwandelt.
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon superracer » Mi 11 Okt, 2006 11:56

ein double ist eh "quasi dezimal", wenn du ein printf("%f") drauf machst, kriegst du sie als dezimal rausgeprintet.

wenn dein programm eine dezimalzahl in eine beliebige basis umwandelt, wirst du die zahl wohl auch mal als int oder double vorliegen haben, oder?
superracer
Board-User Level 3
Board-User Level 3
 
Beiträge: 1073
Registriert: So 04 Jul, 2004 11:18

Beitragvon moonangel » Mi 11 Okt, 2006 12:14

momentan habe ich:

void main()
{
float x;
x = umwandler("10.10", 16);
printf("%f \n", x);

}

sollte eigentlich "16.16" rauskommen, kommt aber
"16.06250" :(
bin grad ein bischen verzweifelt ..
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon moonangel » Mi 11 Okt, 2006 12:16

#include "stdafx.h"

double umwandler(char *zahl, unsigned int basis);
static unsigned int basedig(unsigned char dig, unsigned int basis) ;
//basedig=funktion, die eine ziffer (char 0-9, a-z) als int (dezimal) zurĂĽckgibt. wobei mir gerade auffallt, daĂź der "base" parameter hier nicht verwendet wird.

void main()
{
float x;
x = umwandler("-10.10", 16);
printf("%f \n", x);

}
static unsigned int basedig(unsigned char dig, unsigned int basis)
{
if (dig >= '0' && dig <= '9')
return dig - '0';
else if (dig >= 'A' && dig <= 'Z')
return dig - 'A' + 10;
return -1;
}

double umwandler(char *zahl, unsigned int basis)
{
/* zahl: string in form von zb "32fac2" */
/* base: 2 .. 36 */
unsigned int ret, dig; //dig=wert (0-35) der aktuell bearbeiteten ziffer
double nc, fact, exp; //nc=Nachkommateil der Zahl,fact=Vorzeichen,exp=exponent wird zum durchdividieren der einzelnen stellen des nachkommateils gebraucht
unsigned char *cp; //char pointer, damit wird der string von anfang bis ende zeichen fĂĽr zeichen durchgehatscht

if (!zahl || basis < 2 || basis > 36)
return -1;

ret = 0;
nc = 0;
fact = 1; // Variable fĂĽr das Vorzeichen
cp = (unsigned char *) zahl;

/* fĂĽhrende spaces ĂĽberspringen */
while (*cp == ' ')
cp++;

if (*cp == '-')
{
fact = -1;
cp++;
}

while (*cp)
{
dig = basedig(*cp, basis);
if (dig == -1)
break; /* konvertierung stoppt beim ersten ungĂĽltigen zeichen */
if (dig >= basis)
break; /* konvertierung stoppt beim ersten ungĂĽltigen zeichen */
ret=ret*basis;
ret=ret+dig;
cp++;
}

if (*cp == '.')
{
cp++;
exp = basis;

while (*cp)
{
dig = basedig(*cp, basis);
if (dig == -1)
break;
if (dig >= basis)
break;
nc += dig / exp;
exp *= basis;
cp++;
}
}

return fact * (nc + ret); //gibt das endergebnis zurĂĽck, bestehend aus vorzeichen (fact), ganzzahliger anteil (ret) und nachkommateil (nc)

}
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon hellbringer » Mi 11 Okt, 2006 12:17

10.10 hex ergibt doch eh 16.0625 dezimal, oder was meinst du?
hellbringer
Profi-User
Profi-User
 
Beiträge: 1619
Registriert: Di 04 Mai, 2004 19:35

Beitragvon moonangel » Mi 11 Okt, 2006 12:21

eben DEZIMAL. ich möchte 10.10 von hexadezimal in binär z.b. umwandeln
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon superracer » Mi 11 Okt, 2006 12:23

dann stopfst du das ergebnis in deine dezimal-nach-beliebig funktion (mit basis 2) und fertig?
superracer
Board-User Level 3
Board-User Level 3
 
Beiträge: 1073
Registriert: So 04 Jul, 2004 11:18

Beitragvon moonangel » Mi 11 Okt, 2006 12:29

nein leider weil meine dezimal in dbeliebig kein nachkomma und vorzeichen beachtet
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon superracer » Mi 11 Okt, 2006 12:41

dann poste vl mal was du schon hast?

(langsam wirds mĂĽhsam)
superracer
Board-User Level 3
Board-User Level 3
 
Beiträge: 1073
Registriert: So 04 Jul, 2004 11:18

Beitragvon moonangel » Mi 11 Okt, 2006 12:44

(langsam wirds mĂĽhsam)



ja fĂĽr mich auch :(


wie schon mal gesagt ICH habe:


#include <stdio.h>
void main()
{
int summe=0;
int basis,ziffer,zahl;
printf("Geben Sie bitte Ihre Basis ein:\n");
scanf("%d",&basis);
printf("Geben Sie bitte Ihre Zahl ein:\n");
scanf("%d",&zahl);
while((zahl>0)
{
ziffer=zahl%basis;
printf("%d",ziffer);
zahl=zahl/basis;
}

}
//umwandeln einer zahl von dezimal in beliebig


und eben siehe oben:


#include "stdafx.h"
double umwandler(char *zahl, unsigned int basis);
static unsigned int basedig(unsigned char dig, unsigned int basis) ;
//basedig=funktion, die eine ziffer (char 0-9, a-z) als int (dezimal) zurĂĽckgibt. wobei mir gerade auffallt, daĂź der "base" parameter hier nicht verwendet wird.

void main()
{
float x;
x = umwandler("-10.10", 16);
printf("%f \n", x);

}
static unsigned int basedig(unsigned char dig, unsigned int basis)
{
if (dig >= '0' && dig <= '9')
return dig - '0';
else if (dig >= 'A' && dig <= 'Z')
return dig - 'A' + 10;
return -1;
}

double umwandler(char *zahl, unsigned int basis)
{
/* zahl: string in form von zb "32fac2" */
/* base: 2 .. 36 */
unsigned int ret, dig; //dig=wert (0-35) der aktuell bearbeiteten ziffer
double nc, fact, exp; //nc=Nachkommateil der Zahl,fact=Vorzeichen,exp=exponent wird zum durchdividieren der einzelnen stellen des nachkommateils gebraucht
unsigned char *cp; //char pointer, damit wird der string von anfang bis ende zeichen fĂĽr zeichen durchgehatscht

if (!zahl || basis < 2 || basis > 36)
return -1;

ret = 0;
nc = 0;
fact = 1; // Variable fĂĽr das Vorzeichen
cp = (unsigned char *) zahl;

/* fĂĽhrende spaces ĂĽberspringen */
while (*cp == ' ')
cp++;

if (*cp == '-')
{
fact = -1;
cp++;
}

while (*cp)
{
dig = basedig(*cp, basis);
if (dig == -1)
break; /* konvertierung stoppt beim ersten ungĂĽltigen zeichen */
if (dig >= basis)
break; /* konvertierung stoppt beim ersten ungĂĽltigen zeichen */
ret=ret*basis;
ret=ret+dig;
cp++;
}

if (*cp == '.')
{
cp++;
exp = basis;

while (*cp)
{
dig = basedig(*cp, basis);
if (dig == -1)
break;
if (dig >= basis)
break;
nc += dig / exp;
exp *= basis;
cp++;
}
}

return fact * (nc + ret); //gibt das endergebnis zurĂĽck, bestehend aus vorzeichen (fact), ganzzahliger anteil (ret) und nachkommateil (nc)

}
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon superracer » Mi 11 Okt, 2006 13:31

while((zahl>0)
{
ziffer=zahl%basis;
printf("%d",ziffer);
zahl=zahl/basis;
}

sorry, aber das is blödsinn, und zwar in zweierlei hinsicht. hast du da überhaupt schon mal ausprobiert, was da rauskommt?
superracer
Board-User Level 3
Board-User Level 3
 
Beiträge: 1073
Registriert: So 04 Jul, 2004 11:18

Beitragvon moonangel » Mi 11 Okt, 2006 13:48

jaaa. und es funktioniert.
den 5 in binär ist 1010.
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon superracer » Mi 11 Okt, 2006 13:51

nein, 5 in binär ist 101. aber probier mal 13 (1101) umrechnen.
auĂźerdem probiers mal mit konvertierung in hex.
superracer
Board-User Level 3
Board-User Level 3
 
Beiträge: 1073
Registriert: So 04 Jul, 2004 11:18

Beitragvon moonangel » Mi 11 Okt, 2006 13:58

hmm 13 in binär is da 1011 ..
oh A2B2C4 nimmt er gar nicht.
ich hasse programmieren :(
ich mein ich komm hier ja
sicher wie der letzte trottel rĂĽber
der von nichts ne ahnung hat.
ich will doch nur dieses eine doofe
programm :(
moonangel
Junior Board-Mitglied
Junior Board-Mitglied
 
Beiträge: 49
Registriert: Sa 04 Mär, 2006 16:14

Beitragvon superracer » Mi 11 Okt, 2006 14:09

dein problem war, daĂź du erstens das ganze verkehrt rausgeprintet hast, zweitens zifferwerte >= 10 nicht berĂĽcksichtigt hast.

meine lösung dafür:
Code: Alles auswählen
static char digitvalue(unsigned int digit, unsigned int base, int ucase) {
        if (digit > base)
                return '?';
        if (digit <= 9)
                return '0' + digit;
        return (ucase ? 'A' : 'a') + digit - 10;
}

void conv_to_base(double x, unsigned int base, char *buf, int ucase) {
        double exp;

        if (x < 0) {
                *buf++ = '-';
                x *= -1;
        }

        if (x == 0) {
                *buf = '0';
                return;
        }

        exp = base;
        while ((exp * base) < x)
                exp *= base;

        while (exp >= 1 || x != 0) {
                *buf++ = digitvalue(x / exp, base, ucase);
                x -= ((unsigned int) (x / exp)) * exp;
                if (exp == 1 && x != 0)
                        *buf++ = '.';
                exp /= base;
        }

        *buf = '\0';
}


achtung, buffer overflow :D

test:
Code: Alles auswählen
int main() {
        char buf[64];
        conv_to_base(-355623.9921875, 16, buf, 0);
        printf("%s\n", buf);
        return 0;
}


gibt "-56d27.fe" aus.
superracer
Board-User Level 3
Board-User Level 3
 
Beiträge: 1073
Registriert: So 04 Jul, 2004 11:18

VorherigeNächste

ZurĂĽck zu PROGRAMMIER FORUM

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 17 Gäste