Bruchrechensystem(Integer)

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Marek

Betreff: Bruchrechensystem(Integer)

BeitragSa, Feb 23, 2008 3:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Weil ich es für mein Projekt grade brauche, habe ich mal ein Bruchrechensystem auf Integer-Basis für Blitz gebastelt...

Es geht bereits...
...addieren, subtrahieren, multiplizieren, dividieren, Brüche in eine Datei schreiben, Brüche auf dem Bildschirm ausgeben, Brüche aus 'normalen' Floats erstellen, einen Bruch zu einem Float umrechnen, Informationen wie Breite/Höhe zu einem Bruch bekommen, die Einzelteile(Integer, Numerator, Denuminator) zurückliefern lassen und (logischerweise) einen Bruch löschen.

Es geht noch nicht/Es fehlt noch...
...Wurzeln ziehen(ist auch unlogisch...), Stringrechenfunktionen(kommen bei Bedarf noch) und periodische Floats zu Brüchen umrechnen(, was mir besonders ein Dorn im Auge ist. Wenn jemand weiß, wie man soetwas umsetzen kann... Ich kann Tips gut gebrauchen^^).

und hier der Code:
Code: [AUSKLAPPEN]
Global CurrentID
Dim Fraction(CurrentID,2)
Dim TempFraction(0,0)
Type DeletedFractions
   Field ID
End Type

Function CreateFraction(Numerator,Denuminator=1,Integer=0)
   Local every.DeletedFractions,ID=-1
   For every.DeletedFractions=Each DeletedFractions
      ID=every\ID
      Delete every
      Exit
   Next
   If ID=-1 Then
      ReDim()
      If Numerator=0 Then Denuminator=1
      Fraction(CurrentID,0)=Integer
      Fraction(CurrentID,1)=Numerator
      Fraction(CurrentID,2)=Denuminator
      CurrentID=CurrentID+1
      TrimFraction(CurrentID-1)
      Return CurrentID-1
   Else
      If Numerator=0 Then Denuminator=1
      Fraction(ID,0)=Integer
      Fraction(ID,1)=Numerator
      Fraction(ID,2)=Denuminator
      TrimFraction(ID)
      Return ID
   EndIf
End Function

Function FloatToFraction(FloatVar#)
   Local temp
   Local every.DeletedFractions,ID=-1
   For every.DeletedFractions=Each DeletedFractions
      ID=every\ID
      Delete every
      Exit
   Next
   If ID=-1 Then
      ReDim()
   EndIf
   While FloatVar#>=1
      temp=temp+1
      FloatVar#=FloatVar#-1
   Wend
   If ID=-1 Then
      Fraction(CurrentID,0)=temp
      Fraction(CurrentID,1)=Int(FloatVar#*1000000)
      Fraction(CurrentID,2)=1000000
      CurrentID=CurrentID+1
      TrimFraction(CurrentID-1)
      Return CurrentID-1
   Else
      Fraction(ID,0)=temp
      Fraction(ID,1)=Int(FloatVar#*1000000)
      Fraction(ID,2)=1000000
      TrimFraction(ID)
      Return ID
   EndIf
End Function

Function DeleteFraction(ID)
   Local created.DeletedFractions=New DeletedFractions
   created\ID=ID
End Function

Function MultiplyFractions(ID1,ID2)
   Local Integer1=Fraction(ID1,0),Integer2=Fraction(ID2,0)
   Local Numerator1=Fraction(ID1,1),Numerator2=Fraction(ID2,1)
   Local Denuminator1=Fraction(ID1,2),Denuminator2=Fraction(ID2,2)
   Local Numerator,Denuminator,ID
   Numerator=(Numerator1+Integer1*Denuminator1)*(Numerator2+Integer2*Denuminator2)
   Denuminator=Denuminator1*Denuminator2
   ID=CreateFraction(Numerator,Denuminator)
   TrimFraction(ID)
   Return ID
End Function

Function DivideFractions(ID1,ID2)
   Local Integer1=Fraction(ID1,0),Integer2=Fraction(ID2,0)
   Local Numerator1=Fraction(ID1,1),Numerator2=Fraction(ID2,1)
   Local Denuminator1=Fraction(ID1,2),Denuminator2=Fraction(ID2,2)
   Local Numerator,Denuminator,ID
   Numerator1=Numerator1+Integer1*Denuminator1
   Numerator2=Numerator2+Integer2*Denuminator2
   If Numerator2<0 Then
      Numerator2=Numerator2*-1
      Denuminator2=Denuminator2*-1
   EndIf
   Numerator=Numerator1*Denuminator2
   Denuminator=Denuminator1*Numerator2
   ID=CreateFraction(Numerator,Denuminator)
   TrimFraction(ID)
   Return ID
End Function

Function SumFractions(ID1,ID2)
   Local Integer1=Fraction(ID1,0),Integer2=Fraction(ID2,0)
   Local Numerator1=Fraction(ID1,1),Numerator2=Fraction(ID2,1)
   Local Denuminator1=Fraction(ID1,2),Denuminator2=Fraction(ID2,2)
   Local Numerator,Denuminator,ID
   Denuminator=GetkgV(Denuminator1,Denuminator2)
   Numerator1=Numerator1+Denuminator1*Integer1
   Numerator2=Numerator2+Denuminator2*Integer2
   Numerator=Numerator1*(Denuminator/Denuminator1)+Numerator2*(Denuminator/Denuminator2)
   ID=CreateFraction(Numerator,Denuminator)
   TrimFraction(ID)
   Return ID
End Function

Function SubtractFractions(ID1,ID2)
   Local Integer1=Fraction(ID1,0),Integer2=Fraction(ID2,0)
   Local Numerator1=Fraction(ID1,1),Numerator2=Fraction(ID2,1)
   Local Denuminator1=Fraction(ID1,2),Denuminator2=Fraction(ID2,2)
   Local Numerator,Denuminator,ID
   Denuminator=GetkgV(Denuminator1,Denuminator2)
   Numerator1=Numerator1+Denuminator1*Integer1
   Numerator2=Numerator2+Denuminator2*Integer2
   Numerator=Numerator1*(Denuminator/Denuminator1)-Numerator2*(Denuminator/Denuminator2)
   ID=CreateFraction(Numerator,Denuminator)
   TrimFraction(ID)
   Return ID
End Function

Function TrimFraction(ID)
   Local Integer=Fraction(ID,0)
   Local Numerator=Fraction(ID,1)
   Local Denuminator=Fraction(ID,2)
   Local count,temp,ggT
   If Integer<0 Then count=count+1
   If Numerator<0 Then count=count+1
   If Denuminator<0 Then count=count+1
   Select count
      Case 1
         If Numerator<0 Then
            If Not Integer=0 Then
               Numerator=Numerator*-1
               Integer=Integer*-1
            EndIf
         ElseIf Denuminator<0 Then
            If Not Integer=0 Then
               Denuminator=Denuminator*-1
               Integer=Integer*-1
            Else
               Denuminator=Denuminator*-1
               Numerator=Numerator*-1
            EndIf
         EndIf
      Case 2
         If Integer<0 Then Integer=Integer*-1
         If Numerator<0 Then Numerator=Numerator*-1
         If Denuminator<0 Then Denuminator=Denuminator*-1
      Case 3
         Numerator=Numerator*-1
         Denuminator=Denuminator*-1
   End Select
   If Integer=0 And count=1 Then
      temp=Numerator*-1
      While temp>Denuminator
         Integer=Integer-1
         temp=temp-Denuminator
      Wend
      If Not Integer=0 Then Numerator=temp
   Else
      While Numerator>Denuminator
         Integer=Integer+1
         Numerator=Numerator-Denuminator
      Wend
   EndIf
   ggT=GetggT(Numerator,Denuminator)
   Numerator=Numerator/ggT
   Denuminator=Denuminator/ggT
   If Numerator=Denuminator Then
      Integer=Integer+1
      Numerator=0
   EndIf
   Fraction(ID,0)=Integer
   Fraction(ID,1)=Numerator
   Fraction(ID,2)=Denuminator
End Function

Function GetggT(Zahl1,Zahl2)
    Local Counter
   Local ggT
   Local Tmp
   If Zahl1 < Zahl2 Then
      Tmp = Zahl1
      Zahl1 = Zahl2
      Zahl2 = Tmp
   EndIf
   For Counter = Zahl1 To 0 Step -1
      If Float(Zahl1)/Float(Counter) = Zahl1/Counter Then
         If Float(Zahl2)/Float(Counter) = Zahl2/Counter Then
            ggT = Counter
            Exit
         EndIf
      EndIf       
   Next
   Return ggT
End Function

Function GetkgV(Zahl1,Zahl2)
    Local Counter
   Local kgV
   While Not kgV
      Counter = Counter + 1
      If Float(Counter)/Float(Zahl1) = Counter/Zahl1 Then
         If Float(Counter)/Float(Zahl2) = Counter/Zahl2 Then
            kgV = Counter
         EndIf
      EndIf
   Wend
   Return kgV
End Function

Function WriteFraction(Stream,ID)
   WriteInt(Stream,Fraction(ID,0))
   WriteInt(Stream,Fraction(ID,1))
   WriteInt(Stream,Fraction(ID,2))
End Function

Function ReadFraction(Stream)
   Local Integer=ReadInt(Stream)
   Local Numerator=ReadInt(Stream)
   Local Denuminator=ReadInt(Stream)
   Local every.DeletedFractions,ID=-1
   For every.DeletedFractions=Each DeletedFractions
      ID=every\ID
      Delete every
      Exit
   Next
   If ID=-1 Then
      ReDim()
      If Numerator=0 Then Denuminator=1
      Fraction(CurrentID,0)=Integer
      Fraction(CurrentID,1)=Numerator
      Fraction(CurrentID,2)=Denuminator
      CurrentID=CurrentID+1
      TrimFraction(CurrentID-1)
      Return CurrentID-1
   Else
      If Numerator=0 Then Denuminator=1
      Fraction(ID,0)=Integer
      Fraction(ID,1)=Numerator
      Fraction(ID,2)=Denuminator
      TrimFraction(ID)
      Return ID
   EndIf
End Function

Function TextFraction(x,y,ID,CenterX=False,CenterY=False)
   Local Width=GetFractionWidth(ID), Height=GetFractionHeight(ID)
   Local Integer=Fraction(ID,0), IntHeight=StringHeight(Integer), IntWidth=StringWidth(Integer)
   Local Numerator=Fraction(ID,1), NumHeight=StringHeight(Numerator), NumWidth=StringWidth(Numerator)
   Local Denuminator=Fraction(ID,2), DenHeight=StringHeight(Denuminator), DenWidth=StringWidth(Denuminator)
   Local tempx, tempy, tempwidth, x2=x, y2=y
   If CenterX=True Then
      x2=x2-Width/2
   EndIf
   If CenterY=True Then
      y2=y2-Height/2
   EndIf
   tempy=y2
   tempy=tempy+Height/2
   If Numerator=0 Then
      Text x2-1,tempy,Integer,0,1
   EndIf
   If Not Integer=0 Then
      Text x2-1,tempy,Integer,0,1   
   Else
      If Numerator<0 Then
         Text x2-1,tempy,"-",0,1
         Numerator=Numerator*-1
      EndIf
   EndIf
   If Not Numerator=0 Then
      tempwidth=Width-IntWidth-1
      tempx=x2+IntWidth+1+tempwidth/2
      Text tempx-1,y2,Numerator,1,0
      Line x2+IntWidth,y2+NumHeight+2,x2+Width-2,y2+NumHeight+2
      tempy=y2+NumHeight+4
      Text tempx-1,tempy,Denuminator,1,0
   EndIf
End Function

Function GetFractionWidth(ID)
   Local Integer=Fraction(ID,0)
   Local Numerator=Fraction(ID,1)
   Local Denuminator=Fraction(ID,2)
   Local Width=0,temp
   If Not Integer=0
      Width=Width+StringWidth(Integer)
      If Not Numerator=0
         Width=Width+2
      EndIf
   Else
      If Numerator<0 Then Width=Width+StringWidth("-")+2
   EndIf
   If Not Numerator=0 Then
      temp=Len(Numerator)
      If StringWidth(Denuminator)>temp Then
         Width=Width+StringWidth(Denuminator)
      Else
         Width=Width+StringWidth(Numerator)
      EndIf
   EndIf
   Return Width
End Function

Function GetFractionHeight(ID)
   Local Integer=Fraction(ID,0)
   Local Numerator=Fraction(ID,1)
   Local Denuminator=Fraction(ID,2)
   Local Height=0,temp
   If Numerator=0 Then
      Height=StringHeight(Integer)
   Else
      Height=StringHeight(Numerator)+3+StringHeight(Denuminator)
   EndIf
   Return Height
End Function

Function GetInteger(ID)
   Return Fraction(ID,0)
End Function

Function GetNumerator(ID)
   Return Fraction(ID,1)
End Function

Function GetDenuminator(ID)
   Return Fraction(ID,2)
End Function

Function ReDim()
   Dim TempFraction(CurrentID-1,2)
   Local x,y
   For x=0 To (CurrentID-1)
      For y=0 To 2
         TempFraction(x,y)=Fraction(x,y)
      Next
   Next
   Dim Fraction(CurrentID,2)
   For x=0 To (CurrentID-1)
      For y=0 To 2
         Fraction(x,y)=TempFraction(x,y)
      Next
   Next
End Function

Function FractionToFloat(ID)
   Local Integer=Fraction(ID,0)
   Local Numerator=Fraction(ID,1)
   Local Denuminator=Fraction(ID,2)
   Local RetFloat#=Float(Integer)
   RetFloat#=RetFloat#+Float(Numerator)/Float(Denuminator)
   Return RetFloat#
End Function


Die komplette Datei (inclusive Funktionsbeschreibung) kann außerdem noch hier gedownloadet werden Wink

Have fun with it!

MfG Marek
Wer lesen kann ist klar im Vorteil...

Rallimen

Sieger des 30-EUR-Wettbewerbs

BeitragMi, März 19, 2008 1:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
und periodische Floats zu Brüchen umrechnen(, was mir besonders ein Dorn im Auge ist. Wenn jemand weiß, wie man soetwas umsetzen kann... Ich kann Tips gut gebrauchen^^).



Code: [AUSKLAPPEN]
bei 0.333333333  ist 3 die Periode

      _
bzw 0,3

da wird dann nicht einfach 3/10 geschrieben sondern eine 9 als Nenner
weil die Periode nur eine Ziffer hat
daraus ergibt sich 3/9 .... gekürzt also 1/3

Bei längeren Perioden halt soviele 9er wir die Periode lang ist
Beispiel:
  __
0.34
= 34/99


Hab das jetzt mal in CodeTags gesetzt da die Periodenstriche sonst nicht richtig angezeigt werden
[BB2D | BB3D | BB+]

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group