Παρασκευή, 8 Απριλίου 2016

Πρόσθεση Και Αφαίρεση Μεγάλων Αριθμών.


Σε μια κλάση έχουμε όλα τα απαραίτητα. Για να κάνουμε αφαίρεση βρίσκουμε το συμπληρωματικό ως προς 1 και μετά προσθέτουμε.. Η πρόσθεση βγάζει ένα 1 επιπλέον το οποίο κόβουμε και παράλληλα αφαιρούμε και τυχόν μηδενικά.
Και σε αυτό το παράδειγμα έχουμε αριθμούς >=0. Η αφαίρεση απαιτεί Α>=Β αλλιώς βγαίνει εσκεμμένα λάθος (επειδή δεν έχω βάλει ακόμα πρόσημο στην κλάση).

Διορθώθηκε, έλειπε η Error και έχει σημειωθεί με κίτρινο χρώμα. Η Error ή Λάθος παράγει λάθος και τερματίζει το πρόγραμμα με σήμανση του λάθους. Μπορεί κανείς να βάζει την Try ή Δες και να ακολουθεί μπλοκ στο οποίο τα λάθη διαγράφονται, και το πρόγραμμα συνεχίζει, ή να βάλουμε την Try ή Δες με μια μεταβλητή πχ Οκ και διαβάζουμε αυτήν μετά το μπλοκ καθώς και την μεταβλητή μόνο για ανάγνωση Error ή Λάθος, για να δούμε αν έχουμε λάθος και να το δείξουμε με την Error$ ή Λάθος$ χωρίς να σταματήσει το πρόγραμμα. Το Ok ή άλλη μεταβλητή γίνεται 0 αν το λάθος είναι στις γραμμές του μπλοκ και όχι σε κάτι που καλείται από εκεί, και για το λόγο αυτό διαβάζουμε και την Error.



Class Num {
      Val$="0"
      Module Num {
            If Match("S") then {
                  Read .Val$
            } Else {
                  .Val$<=Str$(Number,"0")
            }
      }
      Module Complement {
           read many
           b$=""  : m%=1
           If many>len(.Val$) then .Val$<=string$("0",many-len(.Val$))+.Val$
           For i=len(.Val$) to 1 {
                 m%=9-val(mid$(.Val$, i,1))+m%
                 mm%=m%-10
                 if m%<10 then {
                  b$=str$(m%,"0")+b$ : m%=0
                }   else b$=str$(mm%,"0") +b$: m%=1
           }
           .Val$<=Right$(b$, many)
      }
      Function G.T {
            Read A, B
            If Len(A.Val$)=Len(B.Val$) then {
                  =A.Val$>B.Val$
            } Else.If Len(A.Val$)>Len(B.Val$) then {
                  =true
            } Else =false
      }
      Function SubNum {
       Read A, B
       If .G.T(A,B) then {
             B.complement Len(A.Val$)
             B=.AddNum(A, B)
             For B {
                  Many=1
                  i=len(.Val$)
                  If i>many then {
                      while many<i {
                        If mid$(.val$,many+1,1)<>"0" then exit
                        many++
                  }
                  if many=i then many--
                        .val$<=mid$(.val$, many+1)
                  }
             }
             =B
       } Else Error "Error, A<B"       
      }
      Function AddNum {
            Read A, B
            Dim M$(Max.Data(len(A.Val$)+1,Len(B.Val$)+1)+1)
            If Len(A.Val$)>Len(B.Val$) Then Push A, B : Read A, B
            M%=0
            ofs=Len(B.Val$)-Len(A.Val$)
        
            For I=Len(A.Val$) to 1 {
                  M%=M%+Val(Mid$(A.Val$, I,1))+Val(Mid$(B.Val$, I+ofs,1))
                  M$(I+ofs+1)=Str$(M% mod 10,"0")
                  M%=-(M%>9)
            }
           If M%>0 Then {
                 While ofs>0 {
                          M%=M%+Val(Mid$(B.Val$, ofs,1))
                          M$(I+ofs)=Str$(M% mod 10,"0")
                          M%=-(M%>9)
                          ofs--
                 }
                 If M%>0 Then {
                      M$(0)=Str$(M% mod 10,"0")
                 }    
           }
           F$=""
           For i=0 to Dimension(M$(),1)-1 {
                 F$=F$+M$(i)
           }
           If ofs>0 Then {
                 A.Num Left$(B.Val$,ofs)+F$
           } Else A.Num F$
           =A
      }
}

Function Place$ {
      Read A, X
      =Right$(String$(" ",X)+A.Val$,X)
}

A=Num("20")
B=Num("3")
F=A.SubNum(A,B) \\  17
F=A.AddNum(F, Num(50)) \\ 67
Print Place$(F,len(A.Val$)+2)

A=Num("99999999999999999999999999999999999999999999999999999999")
B=Num("3")
F=A.SubNum(A,B)
F=A.AddNum(F, Num(50))
Print Place$(F,len(A.Val$)+2)

A=Num(0)
B=A