Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » brueche und ueberlauf

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
21.03.2004, 21:14 Uhr
~racoon
Gast


Hallo NG,

das folgende Programm versucht eine double Variable in zaehler und nenner aufzusplitten. Sie arbeitet noch recht stupide:
Die Zahl c soll umgewandelt werden. So wird einfach der Bruch c/1 solange mir *10 erweitert bis c ganzzahlig ist und anschließend gekürzt.

z.B.: c = 0.12 = 0.12 / 1 = 1.2 /10 = 12 / 100 = 3 / 25


C++:
#include <iostream>

int ggt (int x, int y)
{
    int c;
    if (x < 0) x = -x;
    if (y < 0) y = -y;
    if (y == 0) return x;
    return ggt(y, x % y);
}

main()
{
        double c = 0.12;

    int zaehler, nenner;
    
    for (nenner = 1; ((c * nenner) != nearbyint(c * nenner)); nenner *= 10);
    
    zaehler = (int)nearbyint(c * nenner);

    int ggtzn = ggt(zaehler, nenner);
    zaehler = zaehler / ggtzn;
    nenner = nenner / ggtzn;

    std::cout << zaehler << "/" << nenner << '\n';
}



das funktioniert auch soweit recht gut. jetzt etwas, dass ich noch nicht ganz an der funktionsweise verstehe:
es funktioniert sogar mit c gleich (double)1/3, 1/6 und 1/7. ich hatte mit einem überlauf des integer wertes in der for-schleife gerechnet, wegen der periode. aber: es funktioniert. nicht jedoch mit 1/9, 1/11 oder 1/15. ich bin recht neu in der c++ programmiersprache und kann mir keinen Reim machen.

vielleicht kann mir jemand das erklären oder einen tipp/link zum nachlesen geben.

Danke im Vorraus,
Daniel


Bearbeitung von Pablo:

CPP Tags eingefügt


Dieser Post wurde am 21.03.2004 um 21:16 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.03.2004, 23:47 Uhr
virtual
Sexiest Bit alive
(Operator)


Fließkommazahlen arbeiten nicht genau.
Ich denke, es funktioniert für Brüche mit Nenner kleiner 10, wenn überhaupt.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 21.03.2004 um 23:48 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.03.2004, 23:48 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


hmm ich befürchte das wird so nicht gehen du kannst ihm höchstens vorher sagen ab welche stelle der abschneiden soll
in etwa in der art

C++:
typedef struct{int z;int n;}bruch;

int ggt(int x,int y){for(;x-y;x>y?x-=y:y-=x);return x;}

bruch get_bruch(double n,int s){
    bruch b;
    b.z=n*pow(10,s);
    b.n=pow(10,s);
    n=ggt(b.z,b.n);
    b.z/=n;
    b.n/=n;
return b;
}


int main(){
double zahl=(double)1/5;
int stellen=7;
bruch b=get_bruch(zahl,stellen);
printf("%f=%d/%d",zahl,b.z,b.n);

}



--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
22.03.2004, 08:06 Uhr
~racoon
Gast


Erstmal Danke fuer die Antworten.

Es scheint wirklich nicht fuer periodische Brueche ueber 1/7 zu klappen.
Das abschneiden der Kommastellen ist eine Moeglichkeit. Aber es klappte vorher ja fuer 1/3, 1/6, 1/7. Ich Frage mich aber:
Warum klappt es ueberhaupt? es findet ja offensichtlich auch hier ein ueberlauf statt. Und kann man das nicht ausweiten?

Btw. schoene for-schleife fuer den ggt.

Daniel
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
22.03.2004, 08:36 Uhr
~racoon
Gast


hi Windalf

was ist eigentlich der ggt von 0 und 1?

Daniel
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
22.03.2004, 10:42 Uhr
~racoon
Gast


hi virtual,

ich habe gerade bemerkt, dass es auch noch fuer periodische Brueche ueber 1/10 klappt (z.B. 1/13 oder 1/23).

Wer kann Licht ins Dunkel bringen?

Daniel
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
22.03.2004, 10:56 Uhr
~racoon
Gast


Hier mal eine Liste aller moeglichen Brueche (1/x) bis 50 mit x=

1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 16, 17, 19, 20, 23, 24, 25, 26, 28, 32, 34, 37, 38, 39, 40, 46, 47, 48, 50

Bei allen anderen Werten tritt eine "Floating point exeption" auf.
9, 11, 15, 18, 21, 22, 27, 29, 30, 31, 33, 35, 36, 41, 42, 43, 44, 45, 49
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
22.03.2004, 12:39 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


jetzt komm mir mal nicht mit spezialfällen...
ohne das jetzt genau zu wissen würd ich mal sagen das das die zahl selber die nicht 0 ist ist und wenn man zweimal 0 übergibt ist vermutlich jede ganzahlige zahl > 0 ein ggt
das mit dem ggt war mal vom c-golfspielen, mag sein das da nicht alle spezialfälle berücksichtigt sind, aber das ist ja auch nicht der sinn vom golfen sondern eine funktion mit möglichst wenig ascii-zeichen zu schreiben
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: