Dezimalzahlen in Bruch umwandeln

Anfängerfragen zum Programmieren mit PureBasic.
marl
Beiträge: 13
Registriert: 05.02.2009 17:55
Kontaktdaten:

Dezimalzahlen in Bruch umwandeln

Beitrag von marl »

Hallo, ich weiss nicht ob ich hier richtig bin.
Ich muss in meinem Programm eine beliebige Dezimalzahl in einen Bruch umwandeln. Kennt jemand fertigen Code, der so was kann? Oder kann mir da jemand in der Sache Vorgehensweise weiter helfen?
---------------------------------------------
PB 4.2 und 4.5 WIN XP / WIN 7
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von STARGÅTE »

Vorgehensweise:

Dezimalzahl in 10er, 100er ... Bruch und dann Kürzen:

0,0625 -> 625/10000 -> 1/16

Code: Alles auswählen

; Struktur eines Bruchs
Structure Fraction
	Numerator.i
	Denominator.i
EndStructure

; Erstellt einen Bruch aus einer Fließkommazahl.
Procedure DecimalFraction(*Fraction.Fraction, Float.f)
	Protected Factor.i = 1
	While Int(Float)*1.0 <> Float
		Float * 10
		Factor * 10
	Wend
	*Fraction\Numerator = Float
	*Fraction\Denominator = Factor
EndProcedure

; Kürzt einen Bruch so weit wie es möglich ist.
Procedure SimplifyFraction(*Fraction.Fraction)
	Protected Mod.i
	Protected Numerator.i = *Fraction\Numerator
	Protected Denominator.i = *Fraction\Denominator
	Repeat
		Mod = Numerator % Denominator
		If Mod
			Numerator = Denominator
			Denominator = Mod
		EndIf
	Until Mod = 0
	*Fraction\Numerator / Denominator
	*Fraction\Denominator / Denominator
EndProcedure

; Gibt einen Bruch als Zeichenkette zurück.
Procedure.s ExportFraction(*Fraction.Fraction)
	ProcedureReturn Str(*Fraction\Numerator)+"/"+Str(*Fraction\Denominator)
EndProcedure


;## Beispiel

DecimalFraction(A.Fraction, 0.0625)
Debug ExportFraction(A)
SimplifyFraction(A)
Debug ExportFraction(A)
Hinweis: Problematisch wird es nur, wenn die Float nicht "richtig" dargestellt werden kann (also 0.02 ist 0.01999...), dann müsste man ggf zu Doubles wechseln.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von helpy »

STARGÅTE hat geschrieben:Hinweis: Problematisch wird es nur, wenn die Float nicht "richtig" dargestellt werden kann (also 0.02 ist 0.01999...), dann müsste man ggf zu Doubles wechseln.
Oder Man verwendet den String, verschiebt das Komma um x Stellen, nimmt als Nenner 10^X und kürzt dann.

;-)

lg,
guido
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von CSHW89 »

Ich hatte mal dazu eine kleine Procedure geschrieben, die nicht auf dem 10er-System basiert, sondern auf dem 2er-System (d.h. der Nenner ist eine 2er-Potenz). Hier mal der Code:

Code: Alles auswählen

Procedure Rational(double.d)
  Protected num.q, den.q, add.q, pow.d, i.i, sgn.i
  
  sgn = 1
  If (double < 0)
    double * -1
    sgn = -1
  EndIf
  den = 1
  pow = 1
  k = 0
  While (double > pow)
    pow * 2
    k + 1
  Wend
  i = 61
  Repeat
    pow / 2
    add = 1 << i
    If (k = 0)
      den + add
    Else: k - 1
    EndIf
    If (double => pow)
      double - pow
      num + add
    EndIf
    i - 1
  Until (i = -1)
  num * sgn
  
  Debug num
  Debug den
  Debug StrD(num/den)
EndProcedure

Rational(0.2)
Weiß jetzt grad nicht mehr ganz so genau, wie der funktioniert ^^, aber er tut, was er verspricht.

lg Kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von NicTheQuick »

CSHW89 hat geschrieben:Weiß jetzt grad nicht mehr ganz so genau, wie der funktioniert ^^, aber er tut, was er verspricht.
Bei mir kommt bei deinem Beispiel das hier raus:
Debugger hat geschrieben:922337203685477632
4611686018427387904
0.2000000000
Wenn man das durcheinander teilt, ergibt das zwar ungefähr 0.2, aber schön ist das nicht. Das exakte Ergebnis deines Bruchs wäre übrigens 0.200000000000000011102230246251565404236316680908203125
Außerdem wäre das richtig gekürzt: 3602879701896397/18014398509481984
marl
Beiträge: 13
Registriert: 05.02.2009 17:55
Kontaktdaten:

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von marl »

Super, erst mal allen herzlichen Dank für die schnellen Antworten.

Stargate, der Code ist toll, er berücksichtigt allerdings nicht die periodischen Zahlen, also sowas wie o,33333... oder 0,252525
Hier müsste man von der Berechnung her anders vorgehen. Das könnte ich selbst machen,
ich habe jetzt aber keinen Plan, wie mein Programm so eine periodische Zahl erkennen könnte!?
---------------------------------------------
PB 4.2 und 4.5 WIN XP / WIN 7
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von STARGÅTE »

Wenn du 0.3333 gegeben hast, kann das Programm unmöglich entscheiden, ob du 1/3 meinst, oder wirklich in dem fall 3333/10000.

Das heißt du musst zumindest irgendwie kenntlich machen, ob es sich tatsächlich um eine Periode handelt und ab wann sie beginnt.

Wenn du das dann weißt, kannst du es ähnlich wie mit dem 10er, 100er ... Bruch mit einem 9er, 99er, 999er Bruch machen.

Beispiel:
0.3 = 3/9 = 1/3
0.83 = 8.3 : 10 = 8/10 + 3/90 = 8/10 + 1/30 = 25/30 = 5/6

Weiterführende Infos gibs hier: Dezimalsystem
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von CSHW89 »

NicTheQuick hat geschrieben:
CSHW89 hat geschrieben:Weiß jetzt grad nicht mehr ganz so genau, wie der funktioniert ^^, aber er tut, was er verspricht.
Bei mir kommt bei deinem Beispiel das hier raus:
Debugger hat geschrieben:922337203685477632
4611686018427387904
0.2000000000
Wenn man das durcheinander teilt, ergibt das zwar ungefähr 0.2, aber schön ist das nicht. Das exakte Ergebnis deines Bruchs wäre übrigens 0.200000000000000011102230246251565404236316680908203125
Außerdem wäre das richtig gekürzt: 3602879701896397/18014398509481984
Joa stimmt schon. Erstens ist der Code schon Jahre alt, zweitens ist das halt die Natur der Gleitkommazahlen, dass sie nicht genau 0.2 speichern können, und drittens wegen dem Kürzen kannste ja nochmal Euklid drüber jagen ;).
Gibt aber mit Sicherheit bessere Algorithmen.

lg Kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
marl
Beiträge: 13
Registriert: 05.02.2009 17:55
Kontaktdaten:

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von marl »

Danke Stargate für die Info. Mein Problem ist ja jetzt auch, wie man an einer Zahl erkennt, daß es sich um eine periodische handelt!
---------------------------------------------
PB 4.2 und 4.5 WIN XP / WIN 7
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Dezimalzahlen in Bruch umwandeln

Beitrag von STARGÅTE »

Das habe ich doch angedeutet: Du kannst es nicht erkennen, wenn es nicht "markiert" ist.

Mathematisch mit einem Überstrich über der Periode.
Wenn man keine stilistischen Mittel nutzen kann (wie hier in PB), kann man eine _ oder ¯ voran stellen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten