Changes:
- EQ-Check added
- GT-Check regards sign
- Mul (0,a) and Sub(a,b) removes leading 0s and correct sign, when result=0
Michael

Hi Jack,jack wrote:Michael Vogel, here's a document that may be of interest to you; Modern Computer Arithmetic, Richard Brent and Paul Zimmermann, version 0.1.1, November 2006, http://www.loria.fr/~zimmerma/mca/mca-0.1.1.pdf
Code: Select all
zahl1$ = "-123"
zahl2$ = "456"
PutNumber(@zahl1$, num1)
PutNumber(@zahl2$, num2)
VNFMul(num1, num2, num3)
Debug Number(num3)
Code: Select all
Procedure PutNumber (t.s, *num.VNF)
Protected n, p
; Protected t.s
*num\sign = 0
; t = PeekS(@*s)
n = Len(t) - #VNFLen
Code: Select all
; Version 0.5.0
; Define VNF - Vogels Number Format
#VNFDim=10000; ~90000 Ciphers ;)
Structure VNF
len.w
sign.w
num.l[#VNFDim]
EndStructure
; Signs
#VNFNegative=1
#VNFPositive=0
; Errortypes (len-field)
#VNFUndefined=-1
#VNFInfinitive=-2
#VNFOverflow=-3
#VNFNotImplemented=-4
; Dimensions
#VNFLen=9
#VNFMod=1000000000
Declare.s Number(*num.VNF); String
Declare GetNumber(*s.s,*num.VNF); s <- num
Declare PutNumber(*s.s,*num.VNF); s -> num
Declare VNFNormalize(*a.VNF); a = (a)
Declare VNFError(type,stype,*a.VNF); c = Err
Declare VNFCopy(*a.VNF,*b.VNF); b = a
Declare VNFZero(*a.VNF); a = 0
Declare VNFAbs(*a.VNF); a = |a|
Declare VNFMuW(*a.VNF,b.l,*c.VNF); c = a*b, |b|<10^10
Declare VNFMul(*a.VNF,*b.VNF,*c.VNF); c = a*b
Declare VNFDiv(*a.VNF,*b.VNF,*c.VNF); c = a/b
Declare VNFDiW(*a.VNF,b.l,*c.VNF); c = a/b, |b|<10^10
Declare VNFAdd(*a.VNF,*b.VNF,*c.VNF); c = a+b
Declare VNFSub(*a.VNF,*b.VNF,*c.VNF); c = a-b
Declare VNFSqr(*a.VNF); a = a*a
Declare VNFPow(*a.VNF,b.l,*c.VNF); c = a^b
Declare.l VNFGt(*a.VNF,*b.VNF,abs=0); a>b? or |a|>|b|?
Declare.l VNFEq(*a.VNF,*b.VNF,abs=0); a=b? or |a|=|b|?
Declare.l VNFPositive(*a.VNF); a>=0?
Global VNF_Cache_A.VNF
Global VNF_Cache_B.VNF
Global VNF_Cache_C.VNF
; EndDefine
Procedure.s Number(*num.VNF)
Protected n
Protected t.s
If *num\len<0
Select *num\len
Case #VNFUndefined
t="Undefined"
Case #VNFInfinitive
t="Infinitive"
If *num\sign
t="Minus "+t
EndIf
Case #VNFOverflow
t="Overflow"
Case #VNFNotImplemented
t="Not Implemented"
EndSelect
Else
If *num\sign
t="-"
EndIf
n=*num\len
t+Str(*num\num[n])
While n>0
n-1
t+RSet(Str(*num\num[n]),#VNFLen,"0")
Wend
EndIf
ProcedureReturn t
EndProcedure
Procedure GetNumber(*s.String,*num.VNF)
; ACHTUNG! s ist bei dieser Routine vom Typ String!
; (bei x.string bedeutet dies den Aufruf "GetNumber(x,number)" und die Ausgabe "Debug x\s")
Protected n
Protected t.s
If *num\sign
t="-"
EndIf
n=*num\len
t+Str(*num\num[n])
While n>0
n-1
t+RSet(Str(*num\num[n]),#VNFLen,"0")
Wend
*s\s=t
EndProcedure
Procedure PutNumber(*s.s,*num.VNF)
Protected n,p
Protected t.s
*num\sign=#VNFPositive
t=PeekS(@*s)
n=Len(t)-#VNFLen
While n>0
*num\num[p]=Val(PeekS(@t+n,#VNFLen))
p+1
n-#VNFLen
Wend
n=Val(PeekS(@t,9+n))
If n<0
*num\sign=#VNFNegative
n=-n
EndIf
*num\num[p]=n
*num\len=p
EndProcedure
Procedure VNFNormalize(*a.VNF)
; Strap leading zeros (000.000.000)
If *a\len>=0
While (*a\len>=0) And (*a\num[*a\len]=0)
*a\len-1
Wend
; Value equal Zero? Positiv sign
If *a\len<0
*a\len=0
*a\sign=#VNFPositive
EndIf
EndIf
EndProcedure
Procedure VNFError(type,stype,*a.VNF)
If type>=0
type=stype
EndIf
Debug "ERROR "+Str(type)
*a\len=type
EndProcedure
Procedure VNFCopy(*a.VNF,*b.VNF)
Protected n
n=*a\len
*b\len=n
*b\sign=*a\sign
While n>=0
*b\num[n]=*a\num[n]
n-1
Wend
EndProcedure
Procedure VNFZero(*a.VNF)
*a\len=0
*a\sign=#VNFPositive
*a\num[0]=0
EndProcedure
Procedure VNFAbs(*a.VNF)
*a\sign=#VNFPositive
EndProcedure
Procedure.l VNFEq(*a.VNF,*b.VNF,abs=0)
Protected n,d
If n<>*b\len
ProcedureReturn #False
ElseIf (abs=0) And (*a\sign<>*b\sign)
ProcedureReturn #False
Else
While n>=0
If *a\num[n]<>*b\num[n]
ProcedureReturn #False
EndIf
n-1
Wend
ProcedureReturn #True; a=b
EndIf
EndProcedure
Procedure.l VNFGt(*a.VNF,*b.VNF,abs=0)
Protected n,d
If abs=0
If *a\sign<>*b\sign
If *a\sign=#VNFPositive
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndIf
Else
n=*a\len
If n>*b\len
ProcedureReturn #True
ElseIf n<*b\len
ProcedureReturn #False
Else
While n>=0
d=*a\num[n]-*b\num[n]
If d>0
ProcedureReturn #True
ElseIf d<0
ProcedureReturn #False
EndIf
n-1
Wend
ProcedureReturn #False; a=b
EndIf
EndIf
EndProcedure
Procedure.l VNFPositive(*a.VNF)
If *a\sign=#VNFPositive
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure VNFMuW(*a.VNF,b.l,*c.VNF)
Protected n
Protected m.q
n=*a\len
If n<0
VNFError(n,0,*c.VNF)
Else
If b=0
*c\len=0
*c\sign=#VNFPositive
*c\num[0]=0
Else
If b<0
b=-b
*c\sign=#VNFNegative-*a\sign
Else
*c\sign=*a\sign
EndIf
n=0
Repeat
m+*a\num[n] * b
*c\num[n]=m%#VNFMod
m/#VNFMod
n+1
Until n>*a\len
If m
*c\num[n]=m
Else
n-1
EndIf
*c\len=n
EndIf
EndIf
EndProcedure
Procedure VNFMul(*a.VNF,*b.VNF,*c.VNF)
Protected la
Protected lb
Protected n
Protected s.q
Protected z.q
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
*c\sign=(*a\sign + *b\sign)&1; because #VNFNegative=1
*c\len=*a\len+*b\len+1
For n=0 To *c\len
*c\num[n]=0
Next n
la=0
Repeat
lb=0
z=*b\num[lb]
Repeat
s=*a\num[la] * *b\num[lb] + *c\num[la+lb]
;Debug Str(*a\num[la])+" * "+Str(*b\num[lb])+" + "+Str(*c\num[la+lb+1])
;Debug " = "+StrQ(s)+" -> "+Str(s/#VNFMod)+" | "+Str(s%#VNFMod)
*c\num[la+lb]=s%#VNFMod
*c\num[la+lb+1]+s/#VNFMod
lb+1
Until lb>*b\len
la+1
Until la>*a\len
VNFNormalize(*c)
EndIf
EndProcedure
Procedure VNFDiW(*a.VNF,b.l,*c.VNF)
Protected n
Protected d.q,q.q
n=*a\len
If n<0
VNFError(n,0,*c.VNF)
Else
If b=0
*c\len=#VNFUndefined
Else
If b<0
b=-b
*c\sign=#VNFNegative-*a\sign
Else
*c\sign=*a\sign
EndIf
Repeat
d=d*#VNFMod+*a\num[n]
q=d/b
*c\num[n]=q
d-q*b
n-1
Until n<0
VNFNormalize(*c)
EndIf
EndIf
EndProcedure
Procedure VNFDiv(*a.VNF,*b.VNF,*c.VNF)
Protected n
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
n=*b\len
If n=0
If *b\num[0]=0
*c\len=#VNFUndefined
Else
;Debug "diw"
VNFDiW(*a.VNF,*b\num[0],*c.VNF)
*c\sign=-(1&(*a\sign+*b\sign))
EndIf
Else
If VNFGt(*b,*a,#True)
VNFZero(*c)
Else
; Hmmm...
EndIf
EndIf
EndIf
EndProcedure
Procedure VNFAdd(*a.VNF,*b.VNF,*c.VNF)
Protected n
Protected s
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
If *a\sign<>*b\sign
;Debug "sub"
*b\sign=*a\sign
VNFSub(*a.VNF,*b.VNF,*c.VNF)
Else
*c\sign=*a\sign
If *a\len<*b\len
Swap *a,*b
EndIf
While n<=*a\len
s+*a\num[n]
If n<=*b\len
s+*b\num[n]
EndIf
*c\num[n]=s%#VNFMod
s/#VNFMod
n+1
Wend
If s
*c\num[n]=s
Else
n-1
EndIf
*c\len=n
EndIf
EndIf
EndProcedure
Procedure VNFSub(*a.VNF,*b.VNF,*c.VNF)
Protected n
Protected s
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
If *a\sign<>*b\sign
;Debug "add"
*b\sign=*a\sign
VNFAdd(*a.VNF,*b.VNF,*c.VNF)
Else
If VNFGt(*a.VNF,*b.VNF,#True)
*c\sign=*a\sign
Else
;Debug "swp"
Swap *a,*b
*c\sign=#VNFNegative-*a\sign
EndIf
While n<=*a\len
s+*a\num[n]
If n<=*b\len
s-*b\num[n]
EndIf
If s<0
*c\num[n]=s+#VNFMod
s=-1
Else
*c\num[n]=s
s=0
EndIf
n+1
Wend
*c\len=n-1
VNFNormalize(*c)
EndIf
EndIf
EndProcedure
Procedure VNFSqr(*a.VNF)
If *a\len>=0
VNFMul(*a,*a,VNF_Cache_C)
VNFCopy(VNF_Cache_C,*a)
EndIf
EndProcedure
Procedure VNFPow(*a.VNF,b.l,*c.VNF)
Protected z=0,s,sign
If b<0
; a^b | b<0 not implemented for now...
VNFError(#VNFNotImplemented,0,*c.VNF)
ElseIf *a\len>=0
VNFCopy(*a,VNF_Cache_A)
PutNumber(@"1",VNF_Cache_B)
If VNFPositive(*a)=#False
VNFAbs(VNF_Cache_A)
If b&1 : VNF_Cache_B\Sign=#VNFNegative : EndIf
EndIf
While b>0
s=1<<z
If b&s
VNFMul(VNF_Cache_A,VNF_Cache_B,VNF_Cache_C)
VNFCopy(VNF_Cache_C,VNF_Cache_B)
b-s
EndIf
If b
VNFSqr(VNF_Cache_A)
z+1
EndIf
Wend
VNFCopy(VNF_Cache_B,*c)
EndIf
EndProcedure
x.VNF
y.VNF
z.VNF
;DisableDebugger
time=-GetTickCount_()
Select 44
Case 44
zahl1$ = "-123"
zahl2$ = "456"
PutNumber(@zahl1$, x)
PutNumber(@zahl2$, y)
VNFMul(x,y,z)
Debug Number(z)
EndSelect
time+GetTickCount_()
EnableDebugger
Debug ""
Debug "Calculation time was "+Str(time)+" ms"
I tested the version, that you see after clicking at the link that I provided in my post.Michael Vogel wrote:I got -56088, so I'm not sure which version you were testing
With this version, I get -56088, too. Thanks!Michael Vogel wrote:– here is the latest (I found on my notebook):
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Type V4.0.0
; Project name : Vogels Number Format
; File name : Vogels Number Format.pb
; File Version : 1.0.2
; Programmation : OK
; Programmed by : Guimauve
; Creation Date : 06-07-2012
; Last update : 01-11-2012
; Coded for : PureBasic 5.00 Beta 8
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Programming notes
;
; This code is a re-work of Vogels Number Format orginally
; created by Michel Vogel (PureBasic English Forum).
;
; List of changes :
;
; - VNF structure name : Renamed to "VogelsNumberFormat"
; - Number() ---> Removed : Use VogelsNumberFormat_To_String() instead
; - GetNumber() ---> Removed : Use VogelsNumberFormat_To_String() instead
; - PutNumber() ---> Removed : Use String_To_VogelsNumberFormat() instead
;
; Commands added :
;
; - VogelsNumberFormat_To_String()
; - String_To_VogelsNumberFormat()
; - ReadVogelsNumberFormat()
; - WriteVogelsNumberFormat()
; - VogelsNumberFormat_Factorial() --> Work upto 999!
; - VogelsNumberFormat_Random()
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Size Array Constants <<<<<
#VOGELS_NUMBER_FORMAT_NUM_MAX = 100000
#VOGELS_NUMBER_FORMAT_NEGATIVE = 1
#VOGELS_NUMBER_FORMAT_POSITIVE = 0
#VOGELS_NUMBER_FORMAT_UNDEFINED = -1
#VOGELS_NUMBER_FORMAT_INFINITIVE = -2
#VOGELS_NUMBER_FORMAT_OVERFLOW = -3
#VOGELS_NUMBER_FORMAT_NOT_IMPLEMENTED = -4
#VOGELS_NUMBER_FORMAT_LEN = 9
#VOGELS_NUMBER_FORMAT_MOD = 1000000000
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<
Structure VogelsNumberFormat
Len.w
Sign.w
Num.l[#VOGELS_NUMBER_FORMAT_NUM_MAX]
EndStructure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<
Macro GetVogelsNumberFormatLen(VogelsNumberFormatA)
VogelsNumberFormatA\Len
EndMacro
Macro GetVogelsNumberFormatSign(VogelsNumberFormatA)
VogelsNumberFormatA\Sign
EndMacro
Macro GetVogelsNumberFormatNum(VogelsNumberFormatA, NumID)
VogelsNumberFormatA\Num[NumID]
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<
Macro SetVogelsNumberFormatLen(VogelsNumberFormatA, P_Len)
GetVogelsNumberFormatLen(VogelsNumberFormatA) = P_Len
EndMacro
Macro SetVogelsNumberFormatSign(VogelsNumberFormatA, P_Sign)
GetVogelsNumberFormatSign(VogelsNumberFormatA) = P_Sign
EndMacro
Macro SetVogelsNumberFormatNum(VogelsNumberFormatA, NumID, P_Num)
GetVogelsNumberFormatNum(VogelsNumberFormatA, NumID) = P_Num
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Reset operator <<<<<
Macro ResetVogelsNumberFormat(VogelsNumberFormatA)
ClearStructure(VogelsNumberFormatA, VogelsNumberFormat)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read in Binary file <<<<<
Procedure ReadVogelsNumberFormat(FileID.l, *VogelsNumberFormatA.VogelsNumberFormat)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, ReadWord(FileID))
SetVogelsNumberFormatSign(*VogelsNumberFormatA, ReadWord(FileID))
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
SetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID, ReadLong(FileID))
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write in Binary file <<<<<
Procedure WriteVogelsNumberFormat(FileID.l, *VogelsNumberFormatA.VogelsNumberFormat)
WriteWord(FileID, GetVogelsNumberFormatLen(*VogelsNumberFormatA))
WriteWord(FileID, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
WriteLong(FileID, GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID))
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.005 seconds (25600.00 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Declare VogelsNumberFormat_Add(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Declare VogelsNumberFormat_Sub(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Procedure.s VogelsNumberFormat_To_String(*VogelsNumberFormatA.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
Select GetVogelsNumberFormatLen(*VogelsNumberFormatA)
Case #VOGELS_NUMBER_FORMAT_UNDEFINED
VFN_2_String.s = "Undefined"
Case #VOGELS_NUMBER_FORMAT_INFINITIVE
VFN_2_String = "Infinitive"
If GetVogelsNumberFormatSign(*VogelsNumberFormatA)
VFN_2_String = "Minus " + VFN_2_String
EndIf
Case #VOGELS_NUMBER_FORMAT_OVERFLOW
VFN_2_String = "Overflow"
Case #VOGELS_NUMBER_FORMAT_NOT_IMPLEMENTED
VFN_2_String = "Not Implemented"
EndSelect
Else
If GetVogelsNumberFormatSign(*VogelsNumberFormatA)
VFN_2_String = "-"
EndIf
NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA)
VFN_2_String + Str(GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID))
While NumID > 0
NumID - 1
VFN_2_String + RSet(Str(GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)), #VOGELS_NUMBER_FORMAT_LEN, "0")
Wend
EndIf
ProcedureReturn VFN_2_String
EndProcedure
Procedure String_To_VogelsNumberFormat(*VogelsNumberFormatA.VogelsNumberFormat, String.s)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
NumID = Len(String) - #VOGELS_NUMBER_FORMAT_LEN
While NumID > 0
SetVogelsNumberFormatNum(*VogelsNumberFormatA, p, Val(Mid(String, NumID+1, #VOGELS_NUMBER_FORMAT_LEN)))
p + 1
NumID - #VOGELS_NUMBER_FORMAT_LEN
Wend
NumID = Val(Mid(String, 1, 9 + NumID))
If NumID < 0
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_NEGATIVE)
NumID = -NumID
EndIf
SetVogelsNumberFormatNum(*VogelsNumberFormatA, p, NumID)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, p)
EndProcedure
Procedure VogelsNumberFormat_Normalize(*VogelsNumberFormatA.VogelsNumberFormat)
; Strap leading zeros (000.000.000)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0
While (GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0) And (GetVogelsNumberFormatNum(*VogelsNumberFormatA, GetVogelsNumberFormatLen(*VogelsNumberFormatA)) = 0)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, GetVogelsNumberFormatLen(*VogelsNumberFormatA) - 1)
Wend
; Value equal Zero? Positiv sign
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
SetVogelsNumberFormatLen(*VogelsNumberFormatA, 0)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
EndIf
EndIf
EndProcedure
Procedure VogelsNumberFormat_Error(type, stype, *VogelsNumberFormatA.VogelsNumberFormat)
If type >= 0
type = stype
EndIf
SetVogelsNumberFormatLen(*VogelsNumberFormatA, type)
Debug "ERROR " + Str(type)
ProcedureReturn Type
EndProcedure
Procedure VogelsNumberFormat_Copy(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat)
SetVogelsNumberFormatLen(*VogelsNumberFormatB, GetVogelsNumberFormatLen(*VogelsNumberFormatA))
SetVogelsNumberFormatSign(*VogelsNumberFormatB, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
SetVogelsNumberFormatNum(*VogelsNumberFormatB, NumID, GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID))
Next
EndProcedure
Procedure VogelsNumberFormat_Zero(*VogelsNumberFormatA.VogelsNumberFormat)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, 0)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
For NumID = 0 To #VOGELS_NUMBER_FORMAT_NUM_MAX - 1
SetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID, 0)
Next
EndProcedure
Procedure VogelsNumberFormat_Abs(*VogelsNumberFormatA.VogelsNumberFormat)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
EndProcedure
Procedure VogelsNumberFormat_Equal(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, Abs = 0)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) <> GetVogelsNumberFormatLen(*VogelsNumberFormatB)
ProcedureReturn #False
ElseIf (Abs = 0) And (GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB))
ProcedureReturn #False
Else
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
If GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID) <> GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
ProcedureReturn #False
EndIf
Next
ProcedureReturn #True
EndIf
EndProcedure
Procedure VogelsNumberFormat_GreaterThan(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, Abs = 0)
If Abs = 0
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB)
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) = #VOGELS_NUMBER_FORMAT_POSITIVE
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndIf
Else
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) > GetVogelsNumberFormatLen(*VogelsNumberFormatB)
ProcedureReturn #True
ElseIf GetVogelsNumberFormatLen(*VogelsNumberFormatA) < GetVogelsNumberFormatLen(*VogelsNumberFormatB)
ProcedureReturn #False
Else
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
d = GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID) - GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
If d > 0
ProcedureReturn #True
ElseIf d < 0
ProcedureReturn #False
EndIf
Next
ProcedureReturn #False; a=b
EndIf
EndIf
EndProcedure
Procedure VogelsNumberFormat_Positive(*VogelsNumberFormatA.VogelsNumberFormat)
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) = #VOGELS_NUMBER_FORMAT_POSITIVE
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure VogelsNumberFormat_Mul(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Protected la, lb
Protected s.q, z.q
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, (GetVogelsNumberFormatSign(*VogelsNumberFormatA) + GetVogelsNumberFormatSign(*VogelsNumberFormatB)) & 1)
SetVogelsNumberFormatLen(*VogelsNumberFormatC, GetVogelsNumberFormatLen(*VogelsNumberFormatA) + GetVogelsNumberFormatLen(*VogelsNumberFormatB) + 1)
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatC)
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, 0)
Next
la = 0
Repeat
lb = 0
Repeat
s.q = GetVogelsNumberFormatNum(*VogelsNumberFormatA, la) * GetVogelsNumberFormatNum(*VogelsNumberFormatB, lb) + GetVogelsNumberFormatNum(*VogelsNumberFormatC, la+lb)
SetVogelsNumberFormatNum(*VogelsNumberFormatC, la + lb, s % #VOGELS_NUMBER_FORMAT_MOD)
SetVogelsNumberFormatNum(*VogelsNumberFormatC, la + lb + 1, GetVogelsNumberFormatNum(*VogelsNumberFormatC, la + lb + 1) + s / #VOGELS_NUMBER_FORMAT_MOD)
lb + 1
Until lb > GetVogelsNumberFormatLen(*VogelsNumberFormatB)
la + 1
Until la > GetVogelsNumberFormatLen(*VogelsNumberFormatA)
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
ProcedureReturn Error
EndProcedure
Procedure Private_VogelsNumberFormat_MuW(*VogelsNumberFormatA.VogelsNumberFormat, b.l, *VogelsNumberFormatC.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), 0, *VogelsNumberFormatC)
Else
If b = 0
VogelsNumberFormat_Zero(*VogelsNumberFormatC)
Else
If b < 0
b = -b
SetVogelsNumberFormatSign(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_NEGATIVE - GetVogelsNumberFormatSign(*VogelsNumberFormatA))
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
EndIf
NumID = 0
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
m.q + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID) * b
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, m % #VOGELS_NUMBER_FORMAT_MOD)
m / #VOGELS_NUMBER_FORMAT_MOD
Next
If m
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, m)
Else
NumID - 1
EndIf
SetVogelsNumberFormatLen(*VogelsNumberFormatC, NumID)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure Private_VogelsNumberFormat_DiW(*VogelsNumberFormatA.VogelsNumberFormat, b.l, *VogelsNumberFormatC.VogelsNumberFormat)
Protected NumID
Protected d.q, q.q
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), 0, *VogelsNumberFormatC)
Else
If b = 0
SetVogelsNumberFormatLen(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_UNDEFINED)
Else
If b < 0
b = -b
SetVogelsNumberFormatSign(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_NEGATIVE - GetVogelsNumberFormatSign(*VogelsNumberFormatA))
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
EndIf
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
d = d * #VOGELS_NUMBER_FORMAT_MOD + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
q = d / b
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, q)
d - q * b
Next
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Div(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
If GetVogelsNumberFormatLen(*VogelsNumberFormatB) = 0
If GetVogelsNumberFormatNum(*VogelsNumberFormatB, 0) = 0
SetVogelsNumberFormatLen(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_UNDEFINED)
Else
Private_VogelsNumberFormat_DiW(*VogelsNumberFormatA, GetVogelsNumberFormatNum(*VogelsNumberFormatB, 0), *VogelsNumberFormatC)
SetVogelsNumberFormatSign(*VogelsNumberFormatC, -(1 & (GetVogelsNumberFormatSign(*VogelsNumberFormatA) + GetVogelsNumberFormatSign(*VogelsNumberFormatB))))
EndIf
Else
If VogelsNumberFormat_GreaterThan(*VogelsNumberFormatB, *VogelsNumberFormatA, #True)
VogelsNumberFormat_Zero(*VogelsNumberFormatC)
Else
; Hmmm...
EndIf
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Add(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Protected n
Protected s
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB)
SetVogelsNumberFormatSign(*VogelsNumberFormatB, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
VogelsNumberFormat_Sub(*VogelsNumberFormatA, *VogelsNumberFormatB, *VogelsNumberFormatC)
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < GetVogelsNumberFormatLen(*VogelsNumberFormatB)
Swap *VogelsNumberFormatA, *VogelsNumberFormatB
EndIf
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
s + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
If NumID <= GetVogelsNumberFormatLen(*VogelsNumberFormatB)
s + GetVogelsNumberFormatNum(*VogelsNumberFormatB, NumID)
EndIf
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s % #VOGELS_NUMBER_FORMAT_MOD)
s / #VOGELS_NUMBER_FORMAT_MOD
Next
NumID + 1
If s
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s)
Else
NumID - 1
EndIf
SetVogelsNumberFormatLen(*VogelsNumberFormatC, NumID)
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Sub(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Protected n
Protected s
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB)
SetVogelsNumberFormatSign(*VogelsNumberFormatB, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
VogelsNumberFormat_Add(*VogelsNumberFormatA, *VogelsNumberFormatB, *VogelsNumberFormatC)
Else
If VogelsNumberFormat_GreaterThan(*VogelsNumberFormatA, *VogelsNumberFormatB, #True)
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
Else
Swap *VogelsNumberFormatA, *VogelsNumberFormatB
SetVogelsNumberFormatSign(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_NEGATIVE - GetVogelsNumberFormatSign(*VogelsNumberFormatA))
EndIf
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
s + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
If NumID <= GetVogelsNumberFormatLen(*VogelsNumberFormatB)
s - GetVogelsNumberFormatNum(*VogelsNumberFormatB, NumID)
EndIf
If s < 0
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s + #VOGELS_NUMBER_FORMAT_MOD)
s = -1
Else
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s)
s = 0
EndIf
Next
SetVogelsNumberFormatLen(*VogelsNumberFormatC, NumID)
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Square(*VogelsNumberFormatA.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0
Error = VogelsNumberFormat_Mul(*VogelsNumberFormatA, *VogelsNumberFormatA, VNF_Cache_C.VogelsNumberFormat)
VogelsNumberFormat_Copy(VNF_Cache_C, *VogelsNumberFormatA)
ResetVogelsNumberFormat(VNF_Cache_C)
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Pow(*VogelsNumberFormatA.VogelsNumberFormat, Exponent.l, *VogelsNumberFormatC.VogelsNumberFormat)
Protected z = 0, s, sign
If Exponent < 0
; a^b | b<0 not implemented for now...
VogelsNumberFormat_Error(#VOGELS_NUMBER_FORMAT_NOT_IMPLEMENTED, 0, *VogelsNumberFormatC)
ElseIf GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0
VogelsNumberFormat_Copy(*VogelsNumberFormatA, VNF_Cache_A.VogelsNumberFormat)
String_To_VogelsNumberFormat(VNF_Cache_B.VogelsNumberFormat, "1")
If VogelsNumberFormat_Positive(*VogelsNumberFormatA) = #False
VogelsNumberFormat_Abs(VNF_Cache_A)
If Exponent & 1
SetVogelsNumberFormatSign(VNF_Cache_B, #VOGELS_NUMBER_FORMAT_NEGATIVE)
EndIf
EndIf
While Exponent > 0
s = 1 << z
If Exponent & s
VogelsNumberFormat_Mul(VNF_Cache_A, VNF_Cache_B, VNF_Cache_C.VogelsNumberFormat)
VogelsNumberFormat_Copy(VNF_Cache_C, VNF_Cache_B)
Exponent = Exponent - s
EndIf
If Exponent
VogelsNumberFormat_Square(VNF_Cache_A)
z = z + 1
EndIf
Wend
VogelsNumberFormat_Copy(VNF_Cache_B, *VogelsNumberFormatC)
EndIf
ResetVogelsNumberFormat(VNF_Cache_A)
ResetVogelsNumberFormat(VNF_Cache_B)
ResetVogelsNumberFormat(VNF_Cache_C)
EndProcedure
Procedure VogelsNumberFormat_Factorial(Value.l, *VogelsNumberFormatC.VogelsNumberFormat)
String_To_VogelsNumberFormat(VNF_Cache_B.VogelsNumberFormat, "1")
For Index = 2 To Value
String_To_VogelsNumberFormat(VNF_Cache_C.VogelsNumberFormat, Str(Index))
VogelsNumberFormat_Mul(VNF_Cache_B, VNF_Cache_C, VNF_Cache_R.VogelsNumberFormat)
VogelsNumberFormat_Copy(VNF_Cache_R, VNF_Cache_B)
Next
VogelsNumberFormat_Copy(VNF_Cache_B, *VogelsNumberFormatC)
ResetVogelsNumberFormat(VNF_Cache_B)
ResetVogelsNumberFormat(VNF_Cache_C)
ResetVogelsNumberFormat(VNF_Cache_R)
EndProcedure
Procedure VogelsNumberFormat_Random(*VogelsNumberFormatA.VogelsNumberFormat, MaximumDigitCount.l)
Max = Random(MaximumDigitCount)
For Index = 1 To Max
RandomNumber.s = RandomNumber + Str(Random(9))
Next
If Left(RandomNumber, 1) = "0"
RandomNumber = Right(RandomNumber, Len(RandomNumber) - 1)
EndIf
String_To_VogelsNumberFormat(*VogelsNumberFormatA, RandomNumber)
EndProcedure
Procedure ReadPreferenceVogelsNumberFormat(GroupName.s, *VogelsNumberFormatA.VogelsNumberFormat)
String_To_VogelsNumberFormat(*VogelsNumberFormatA, ReadPreferenceString(GroupName, VogelsNumberFormat_To_String(*VogelsNumberFormatA)))
EndProcedure
Procedure WritePreferenceVogelsNumberFormat(GroupName.s, *VogelsNumberFormatA.VogelsNumberFormat)
WritePreferenceString(GroupName, VogelsNumberFormat_To_String(*VogelsNumberFormatA))
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<<
; <<<<< !!! WARNING - THIS CODE SHOULD BE COMMENTED - WARNING !!! <<<<<
; <<<<< !!! WARNING - BEFORE THE FINAL COMPILATION. - WARNING !!! <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Procedure.s FormatInteger(Number.s)
; Format Integer created by Gnozal
NumberLen = Len(Number)
Start = NumberLen % 3
FormatedNumber.s = Left(Number, Start)
For i = Start + 1 To NumberLen - Start Step 3
FormatedNumber + " " + Mid(Number, i, 3)
Next
ProcedureReturn LTrim(FormatedNumber)
EndProcedure
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(MyNumber.VogelsNumberFormat, "00000000000000000000123456789987654321123456789987654321")
Debug VogelsNumberFormat_To_String(MyNumber)
VogelsNumberFormat_Normalize(MyNumber)
Debug VogelsNumberFormat_To_String(MyNumber)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(X.VogelsNumberFormat, "23456")
String_To_VogelsNumberFormat(Y.VogelsNumberFormat, "98765")
VogelsNumberFormat_Add(X, Y, Z.VogelsNumberFormat)
Debug VogelsNumberFormat_To_String(Z)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(Number1.VogelsNumberFormat, "12345678999999994012121212155454789921999")
String_To_VogelsNumberFormat(Number2.VogelsNumberFormat, "15906045674")
VogelsNumberFormat_Mul(Number1, Number2, Number3.VogelsNumberFormat)
Debug VogelsNumberFormat_To_String(Number1) + " * " + VogelsNumberFormat_To_String(Number2) + " = " + VogelsNumberFormat_To_String(Number3)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(Number.VogelsNumberFormat, "100")
VogelsNumberFormat_Pow(Number, 100, Result.VogelsNumberFormat)
Debug VogelsNumberFormat_To_String(Result)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
For Factorial = 50 To 100
VogelsNumberFormat_Factorial(Factorial, TestFactorial.VogelsNumberFormat)
Debug Str(Factorial) + "! = " + FormatInteger(VogelsNumberFormat_To_String(TestFactorial))
Next
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
For RandomID = 0 To 5
VogelsNumberFormat_Random(TestRandom.VogelsNumberFormat, 25)
Debug FormatInteger(VogelsNumberFormat_To_String(TestRandom))
Next
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Just be sure, it's on the "VogelsNumberFormat_Pow(Number, 100, Result.VogelsNumberFormat)" you get this error ?jack wrote:hello Guimauve
I get a stack overflow at line 769 (Windows 7-32 PB 5 b8), but works OK on my Mac PB x64
Code: Select all
; Version 0.5.0
; Define VNF - Vogels Number Format
#VNFDim = 10000; ~90000 Ciphers ;)
Structure VNF
len.w
sign.w
num.l[#VNFDim]
EndStructure
; Signs
#VNFNegative=1
#VNFPositive=0
; Errortypes (len-field)
#VNFUndefined=-1
#VNFInfinitive=-2
#VNFOverflow=-3
#VNFNotImplemented=-4
; Dimensions
#VNFLen=9
#VNFMod=1000000000
Declare.s Number(*num.VNF) ; String
Declare GetNumber(*s.s,*num.VNF) ; s <- num
Declare PutNumber(s.s,*num.VNF) ; s -> num
Declare VNFNormalize(*a.VNF) ; a = (a)
Declare VNFError(type,stype,*a.VNF) ; c = Err
Declare VNFCopy(*a.VNF,*b.VNF) ; b = a
Declare VNFZero(*a.VNF) ; a = 0
Declare VNFAbs(*a.VNF) ; a = |a|
Declare VNFMuW(*a.VNF,b.l,*c.VNF) ; c = a*b, |b|<10^10
Declare VNFMul(*a.VNF,*b.VNF,*c.VNF); c = a*b
Declare VNFDiv(*a.VNF,*b.VNF,*c.VNF); c = a/b
Declare VNFDiW(*a.VNF,b.l,*c.VNF) ; c = a/b, |b|<10^10
Declare VNFAdd(*a.VNF,*b.VNF,*c.VNF); c = a+b
Declare VNFSub(*a.VNF,*b.VNF,*c.VNF); c = a-b
Declare VNFSqr(*a.VNF) ; a = a*a
Declare VNFPow(*a.VNF,b.l,*c.VNF) ; c = a^b
Declare.l VNFGt(*a.VNF,*b.VNF,abs=0); a > b? or |a| > |b|?
Declare.l VNFEq(*a.VNF,*b.VNF,abs=0); a = b? or |a| = |b|?
Declare.l VNFPositive(*a.VNF) ; a >= 0?
; EndDefine
Procedure.s Number(*num.VNF)
Protected n
Protected t.s
If *num\len<0
Select *num\len
Case #VNFUndefined
t="Undefined"
Case #VNFInfinitive
t="Infinitive"
If *num\sign
t="Minus "+t
EndIf
Case #VNFOverflow
t="Overflow"
Case #VNFNotImplemented
t="Not Implemented"
EndSelect
Else
If *num\sign
t="-"
EndIf
n=*num\len
t+Str(*num\num[n])
While n>0
n-1
t+RSet(Str(*num\num[n]),#VNFLen,"0")
Wend
EndIf
ProcedureReturn t
EndProcedure
Procedure GetNumber(*s.String,*num.VNF)
; ACHTUNG! s ist bei dieser Routine vom Typ String!
; (bei x.string bedeutet dies den Aufruf "GetNumber(x,number)" und die Ausgabe "Debug x\s")
Protected n
Protected t.s
If *num\sign
t = "-"
EndIf
n=*num\len
t+Str(*num\num[n])
While n>0
n-1
t+RSet(Str(*num\num[n]),#VNFLen,"0")
Wend
*s\s=t
EndProcedure
Procedure PutNumber(s.s,*num.VNF)
Protected n,p
Protected t.s
*num\sign=#VNFPositive
t=PeekS(@s)
n=Len(t)-#VNFLen
While n>0
*num\num[p]=Val(PeekS(@t+n,#VNFLen))
p+1
n-#VNFLen
Wend
n=Val(PeekS(@t,9+n))
If n<0
*num\sign=#VNFNegative
n=-n
EndIf
*num\num[p]=n
*num\len=p
EndProcedure
Procedure VNFNormalize(*a.VNF)
; Strap leading zeros (000.000.000)
If *a\len>=0
While (*a\len>=0) And (*a\num[*a\len]=0)
*a\len-1
Wend
; Value equal Zero? Positiv sign
If *a\len<0
*a\len=0
*a\sign=#VNFPositive
EndIf
EndIf
EndProcedure
Procedure VNFError(type,stype,*a.VNF)
If type>=0
type=stype
EndIf
Debug "ERROR "+Str(type)
*a\len=type
EndProcedure
Procedure VNFCopy(*a.VNF,*b.VNF)
Protected n
n=*a\len
*b\len=n
*b\sign=*a\sign
While n>=0
*b\num[n]=*a\num[n]
n-1
Wend
EndProcedure
Procedure VNFZero(*a.VNF)
*a\len=0
*a\sign=#VNFPositive
*a\num[0]=0
EndProcedure
Procedure VNFAbs(*a.VNF)
*a\sign=#VNFPositive
EndProcedure
Procedure.l VNFEq(*a.VNF,*b.VNF,abs=0)
Protected n,d
If n<>*b\len
ProcedureReturn #False
ElseIf (abs=0) And (*a\sign<>*b\sign)
ProcedureReturn #False
Else
While n>=0
If *a\num[n]<>*b\num[n]
ProcedureReturn #False
EndIf
n-1
Wend
ProcedureReturn #True; a=b
EndIf
EndProcedure
Procedure.l VNFGt(*a.VNF,*b.VNF,abs=0)
Protected n,d
If abs=0
If *a\sign<>*b\sign
If *a\sign=#VNFPositive
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndIf
Else
n=*a\len
If n>*b\len
ProcedureReturn #True
ElseIf n<*b\len
ProcedureReturn #False
Else
While n>=0
d=*a\num[n]-*b\num[n]
If d>0
ProcedureReturn #True
ElseIf d<0
ProcedureReturn #False
EndIf
n-1
Wend
ProcedureReturn #False; a=b
EndIf
EndIf
EndProcedure
Procedure.l VNFPositive(*a.VNF)
If *a\sign=#VNFPositive
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure VNFMuW(*a.VNF,b.l,*c.VNF)
Protected n
Protected m.q
n=*a\len
If n<0
VNFError(n,0,*c.VNF)
Else
If b=0
*c\len=0
*c\sign=#VNFPositive
*c\num[0]=0
Else
If b<0
b=-b
*c\sign=#VNFNegative-*a\sign
Else
*c\sign=*a\sign
EndIf
n=0
Repeat
m+*a\num[n] * b
*c\num[n]=m%#VNFMod
m/#VNFMod
n+1
Until n>*a\len
If m
*c\num[n]=m
Else
n-1
EndIf
*c\len=n
EndIf
EndIf
EndProcedure
Procedure VNFMul(*a.VNF,*b.VNF,*c.VNF)
Protected la
Protected lb
Protected n
Protected s.q
Protected z.q
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
*c\sign=(*a\sign + *b\sign)&1; because #VNFNegative=1
*c\len=*a\len+*b\len+1
For n=0 To *c\len
*c\num[n]=0
Next n
la=0
Repeat
lb=0
z=*b\num[lb]
Repeat
s=*a\num[la] * *b\num[lb] + *c\num[la+lb]
;Debug Str(*a\num[la])+" * "+Str(*b\num[lb])+" + "+Str(*c\num[la+lb+1])
;Debug " = "+StrQ(s)+" -> "+Str(s/#VNFMod)+" | "+Str(s%#VNFMod)
*c\num[la+lb]=s%#VNFMod
*c\num[la+lb+1]+s/#VNFMod
lb+1
Until lb>*b\len
la+1
Until la>*a\len
VNFNormalize(*c)
EndIf
EndProcedure
Procedure VNFDiW(*a.VNF,b.l,*c.VNF)
Protected n
Protected d.q,q.q
n=*a\len
If n<0
VNFError(n,0,*c.VNF)
Else
If b=0
*c\len=#VNFUndefined
Else
If b<0
b=-b
*c\sign=#VNFNegative-*a\sign
Else
*c\sign=*a\sign
EndIf
Repeat
d=d*#VNFMod+*a\num[n]
q=d/b
*c\num[n]=q
d-q*b
n-1
Until n<0
VNFNormalize(*c)
EndIf
EndIf
EndProcedure
Procedure VNFDiv(*a.VNF,*b.VNF,*c.VNF)
Protected n
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
n=*b\len
If n=0
If *b\num[0]=0
*c\len=#VNFUndefined
Else
;Debug "diw"
VNFDiW(*a.VNF,*b\num[0],*c.VNF)
*c\sign=-(1&(*a\sign+*b\sign))
EndIf
Else
If VNFGt(*b,*a,#True)
VNFZero(*c)
Else
; Hmmm...
EndIf
EndIf
EndIf
EndProcedure
Procedure VNFAdd(*a.VNF,*b.VNF,*c.VNF)
Protected n
Protected s
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
If *a\sign<>*b\sign
;Debug "sub"
*b\sign=*a\sign
VNFSub(*a.VNF,*b.VNF,*c.VNF)
Else
*c\sign=*a\sign
If *a\len<*b\len
Swap *a,*b
EndIf
While n<=*a\len
s+*a\num[n]
If n<=*b\len
s+*b\num[n]
EndIf
*c\num[n]=s%#VNFMod
s/#VNFMod
n+1
Wend
If s
*c\num[n]=s
Else
n-1
EndIf
*c\len=n
EndIf
EndIf
EndProcedure
Procedure VNFSub(*a.VNF,*b.VNF,*c.VNF)
Protected n
Protected s
If (*a\len<0) Or (*b\len<0)
VNFError(*a\len,*b\len,*c.VNF)
Else
If *a\sign<>*b\sign
;Debug "add"
*b\sign=*a\sign
VNFAdd(*a.VNF,*b.VNF,*c.VNF)
Else
If VNFGt(*a.VNF,*b.VNF,#True)
*c\sign=*a\sign
Else
;Debug "swp"
Swap *a,*b
*c\sign=#VNFNegative-*a\sign
EndIf
While n<=*a\len
s+*a\num[n]
If n<=*b\len
s-*b\num[n]
EndIf
If s<0
*c\num[n]=s+#VNFMod
s=-1
Else
*c\num[n]=s
s=0
EndIf
n+1
Wend
*c\len=n-1
VNFNormalize(*c)
EndIf
EndIf
EndProcedure
Procedure VNFSqr(*a.VNF)
If *a\len>=0
VNFMul(*a,*a,VNF_Cache_C.VNF)
VNFCopy(VNF_Cache_C,*a)
EndIf
EndProcedure
Procedure VNFPow(*a.VNF,b.l,*c.VNF)
Protected z=0,s,sign
If b<0
; a^b | b<0 not implemented for now...
VNFError(#VNFNotImplemented,0,*c.VNF)
ElseIf *a\len>=0
VNFCopy(*a,VNF_Cache_A.VNF)
PutNumber("1",VNF_Cache_B.VNF)
If VNFPositive(*a)=#False
VNFAbs(VNF_Cache_A)
If b & 1
VNF_Cache_B\Sign=#VNFNegative
EndIf
EndIf
While b > 0
s = 1 << z
If b & s
VNFMul(VNF_Cache_A,VNF_Cache_B,VNF_Cache_C.VNF)
VNFCopy(VNF_Cache_C,VNF_Cache_B)
b = b - s
EndIf
If b
VNFSqr(VNF_Cache_A)
z + 1
EndIf
Wend
VNFCopy(VNF_Cache_B,*c)
EndIf
EndProcedure
Procedure VNFRandom(*a.VNF, MaximumDigitCount.l)
Max = Random(MaximumDigitCount)
For Index = 0 To Max
RandomNumber.s = RandomNumber + Str(Random(9))
Next
PutNumber(RandomNumber, *a)
EndProcedure
;// Zone de test
; ;Une addition
; Debug "Demo Addition"
;
; x.VNF
; y.VNF
; z.VNF
;
; A$="12345678999999994012121212155454789921999"
; B$="-1"
;
; DisableDebugger
; time=-ElapsedMilliseconds()
;
; PutNumber(A$,x)
; PutNumber(B$,y)
;
; VNFAdd(x,y,z)
; time+ElapsedMilliseconds()
;
; EnableDebugger
; Debug Number(z)
; Debug "Durée "+Str(time)+" ms"
; Debug ""
;
; ;Une multiplication
; Debug "Demo Multiplication"
; Number1.VNF
; Number2.VNF
; Result.VNF
;
; Number1$="12345678999999994012121212155454789921999"
; Number2$="15906045674"
;
; DisableDebugger
; time = -ElapsedMilliseconds()
;
; PutNumber(Number1$, Number1)
; PutNumber(Number2$, Number2)
;
; VNFMul(Number1, Number2, Result)
; time + ElapsedMilliseconds()
;
; EnableDebugger
;
; Debug Number(Number1) + " * " + Number(Number2) + " = " + Number(Result)
; Debug "Durée "+Str(time)+" ms"
; Debug ""
; ;Puissance
; Debug "Demo Multiplication"
; Number.VNF
; Exponent.l
; Result.VNF
;
; Number$="1000"
; Exponent.l=1000
;
; DisableDebugger
; time=-ElapsedMilliseconds()
;
; PutNumber(Number$,Number)
; VNFPow(Number,Exponent,Result)
; time+ElapsedMilliseconds()
;
; EnableDebugger
; Debug Number(Result)
;
; Debug "Durée "+Str(time)+" ms"
; Debug ""
; For TestID = 0 To 5
; VNFRandom(RandomVNF.VNF, 25)
; Debug Number(RandomVNF)
; Next
; Debug ""
PutNumber("1000", Number.VNF)
VNFPow(Number, 1000,Result.VNF)
Debug Number(Result)
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Type V4.0.0
; Project name : Vogels Number Format
; File name : Vogels Number Format.pb
; File Version : 1.0.2
; Programmation : OK
; Programmed by : Guimauve
; Creation Date : 06-07-2012
; Last update : 01-11-2012
; Coded for : PureBasic 5.00 Beta 8
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Programming notes
;
; This code is a re-work of Vogels Number Format orginally
; created by Michel Vogel (PureBasic English Forum).
;
; List of changes :
;
; - VNF structure name : Renamed to "VogelsNumberFormat"
; - Number() ---> Removed : Use VogelsNumberFormat_To_String() instead
; - GetNumber() ---> Removed : Use VogelsNumberFormat_To_String() instead
; - PutNumber() ---> Removed : Use String_To_VogelsNumberFormat() instead
;
; Commands added :
;
; - VogelsNumberFormat_To_String()
; - String_To_VogelsNumberFormat()
; - ReadVogelsNumberFormat()
; - WriteVogelsNumberFormat()
; - VogelsNumberFormat_Factorial() --> Work upto 999!
; - VogelsNumberFormat_Random()
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Size Array Constants <<<<<
#VOGELS_NUMBER_FORMAT_NUM_MAX = 10000
#VOGELS_NUMBER_FORMAT_NEGATIVE = 1
#VOGELS_NUMBER_FORMAT_POSITIVE = 0
#VOGELS_NUMBER_FORMAT_UNDEFINED = -1
#VOGELS_NUMBER_FORMAT_INFINITIVE = -2
#VOGELS_NUMBER_FORMAT_OVERFLOW = -3
#VOGELS_NUMBER_FORMAT_NOT_IMPLEMENTED = -4
#VOGELS_NUMBER_FORMAT_LEN = 9
#VOGELS_NUMBER_FORMAT_MOD = 1000000000
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<
Structure VogelsNumberFormat
Len.w
Sign.w
Num.l[#VOGELS_NUMBER_FORMAT_NUM_MAX]
EndStructure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<
Macro GetVogelsNumberFormatLen(VogelsNumberFormatA)
VogelsNumberFormatA\Len
EndMacro
Macro GetVogelsNumberFormatSign(VogelsNumberFormatA)
VogelsNumberFormatA\Sign
EndMacro
Macro GetVogelsNumberFormatNum(VogelsNumberFormatA, NumID)
VogelsNumberFormatA\Num[NumID]
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<
Macro SetVogelsNumberFormatLen(VogelsNumberFormatA, P_Len)
GetVogelsNumberFormatLen(VogelsNumberFormatA) = P_Len
EndMacro
Macro SetVogelsNumberFormatSign(VogelsNumberFormatA, P_Sign)
GetVogelsNumberFormatSign(VogelsNumberFormatA) = P_Sign
EndMacro
Macro SetVogelsNumberFormatNum(VogelsNumberFormatA, NumID, P_Num)
GetVogelsNumberFormatNum(VogelsNumberFormatA, NumID) = P_Num
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Reset operator <<<<<
Macro ResetVogelsNumberFormat(VogelsNumberFormatA)
ClearStructure(VogelsNumberFormatA, VogelsNumberFormat)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read in Binary file <<<<<
Procedure ReadVogelsNumberFormat(FileID.l, *VogelsNumberFormatA.VogelsNumberFormat)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, ReadWord(FileID))
SetVogelsNumberFormatSign(*VogelsNumberFormatA, ReadWord(FileID))
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
SetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID, ReadLong(FileID))
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write in Binary file <<<<<
Procedure WriteVogelsNumberFormat(FileID.l, *VogelsNumberFormatA.VogelsNumberFormat)
WriteWord(FileID, GetVogelsNumberFormatLen(*VogelsNumberFormatA))
WriteWord(FileID, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
WriteLong(FileID, GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID))
Next
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.005 seconds (25600.00 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Declare VogelsNumberFormat_Add(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Declare VogelsNumberFormat_Sub(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Procedure.s VogelsNumberFormat_To_String(*VogelsNumberFormatA.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
Select GetVogelsNumberFormatLen(*VogelsNumberFormatA)
Case #VOGELS_NUMBER_FORMAT_UNDEFINED
VFN_2_String.s = "Undefined"
Case #VOGELS_NUMBER_FORMAT_INFINITIVE
VFN_2_String = "Infinitive"
If GetVogelsNumberFormatSign(*VogelsNumberFormatA)
VFN_2_String = "Minus " + VFN_2_String
EndIf
Case #VOGELS_NUMBER_FORMAT_OVERFLOW
VFN_2_String = "Overflow"
Case #VOGELS_NUMBER_FORMAT_NOT_IMPLEMENTED
VFN_2_String = "Not Implemented"
EndSelect
Else
If GetVogelsNumberFormatSign(*VogelsNumberFormatA)
VFN_2_String = "-"
EndIf
NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA)
VFN_2_String + Str(GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID))
While NumID > 0
NumID - 1
VFN_2_String + RSet(Str(GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)), #VOGELS_NUMBER_FORMAT_LEN, "0")
Wend
EndIf
ProcedureReturn VFN_2_String
EndProcedure
Procedure String_To_VogelsNumberFormat(*VogelsNumberFormatA.VogelsNumberFormat, String.s)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
NumID = Len(String) - #VOGELS_NUMBER_FORMAT_LEN
While NumID > 0
SetVogelsNumberFormatNum(*VogelsNumberFormatA, p, Val(Mid(String, NumID+1, #VOGELS_NUMBER_FORMAT_LEN)))
p + 1
NumID - #VOGELS_NUMBER_FORMAT_LEN
Wend
NumID = Val(Mid(String, 1, 9 + NumID))
If NumID < 0
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_NEGATIVE)
NumID = -NumID
EndIf
SetVogelsNumberFormatNum(*VogelsNumberFormatA, p, NumID)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, p)
EndProcedure
Procedure VogelsNumberFormat_Normalize(*VogelsNumberFormatA.VogelsNumberFormat)
; Strap leading zeros (000.000.000)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0
While (GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0) And (GetVogelsNumberFormatNum(*VogelsNumberFormatA, GetVogelsNumberFormatLen(*VogelsNumberFormatA)) = 0)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, GetVogelsNumberFormatLen(*VogelsNumberFormatA) - 1)
Wend
; Value equal Zero? Positiv sign
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
SetVogelsNumberFormatLen(*VogelsNumberFormatA, 0)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
EndIf
EndIf
EndProcedure
Procedure VogelsNumberFormat_Error(type, stype, *VogelsNumberFormatA.VogelsNumberFormat)
If type >= 0
type = stype
EndIf
SetVogelsNumberFormatLen(*VogelsNumberFormatA, type)
Debug "ERROR " + Str(type)
ProcedureReturn Type
EndProcedure
Procedure VogelsNumberFormat_Copy(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat)
SetVogelsNumberFormatLen(*VogelsNumberFormatB, GetVogelsNumberFormatLen(*VogelsNumberFormatA))
SetVogelsNumberFormatSign(*VogelsNumberFormatB, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
SetVogelsNumberFormatNum(*VogelsNumberFormatB, NumID, GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID))
Next
EndProcedure
Procedure VogelsNumberFormat_Zero(*VogelsNumberFormatA.VogelsNumberFormat)
SetVogelsNumberFormatLen(*VogelsNumberFormatA, 0)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
For NumID = 0 To #VOGELS_NUMBER_FORMAT_NUM_MAX - 1
SetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID, 0)
Next
EndProcedure
Procedure VogelsNumberFormat_Abs(*VogelsNumberFormatA.VogelsNumberFormat)
SetVogelsNumberFormatSign(*VogelsNumberFormatA, #VOGELS_NUMBER_FORMAT_POSITIVE)
EndProcedure
Procedure VogelsNumberFormat_Equal(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, Abs = 0)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) <> GetVogelsNumberFormatLen(*VogelsNumberFormatB)
ProcedureReturn #False
ElseIf (Abs = 0) And (GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB))
ProcedureReturn #False
Else
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
If GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID) <> GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
ProcedureReturn #False
EndIf
Next
ProcedureReturn #True
EndIf
EndProcedure
Procedure VogelsNumberFormat_GreaterThan(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, Abs = 0)
If Abs = 0
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB)
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) = #VOGELS_NUMBER_FORMAT_POSITIVE
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndIf
Else
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) > GetVogelsNumberFormatLen(*VogelsNumberFormatB)
ProcedureReturn #True
ElseIf GetVogelsNumberFormatLen(*VogelsNumberFormatA) < GetVogelsNumberFormatLen(*VogelsNumberFormatB)
ProcedureReturn #False
Else
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
d = GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID) - GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
If d > 0
ProcedureReturn #True
ElseIf d < 0
ProcedureReturn #False
EndIf
Next
ProcedureReturn #False; a=b
EndIf
EndIf
EndProcedure
Procedure VogelsNumberFormat_Positive(*VogelsNumberFormatA.VogelsNumberFormat)
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) = #VOGELS_NUMBER_FORMAT_POSITIVE
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure VogelsNumberFormat_Mul(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Protected la, lb
Protected s.q, z.q
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, (GetVogelsNumberFormatSign(*VogelsNumberFormatA) + GetVogelsNumberFormatSign(*VogelsNumberFormatB)) & 1)
SetVogelsNumberFormatLen(*VogelsNumberFormatC, GetVogelsNumberFormatLen(*VogelsNumberFormatA) + GetVogelsNumberFormatLen(*VogelsNumberFormatB) + 1)
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatC)
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, 0)
Next
la = 0
Repeat
lb = 0
Repeat
s.q = GetVogelsNumberFormatNum(*VogelsNumberFormatA, la) * GetVogelsNumberFormatNum(*VogelsNumberFormatB, lb) + GetVogelsNumberFormatNum(*VogelsNumberFormatC, la+lb)
SetVogelsNumberFormatNum(*VogelsNumberFormatC, la + lb, s % #VOGELS_NUMBER_FORMAT_MOD)
SetVogelsNumberFormatNum(*VogelsNumberFormatC, la + lb + 1, GetVogelsNumberFormatNum(*VogelsNumberFormatC, la + lb + 1) + s / #VOGELS_NUMBER_FORMAT_MOD)
lb + 1
Until lb > GetVogelsNumberFormatLen(*VogelsNumberFormatB)
la + 1
Until la > GetVogelsNumberFormatLen(*VogelsNumberFormatA)
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
ProcedureReturn Error
EndProcedure
Procedure Private_VogelsNumberFormat_MuW(*VogelsNumberFormatA.VogelsNumberFormat, b.l, *VogelsNumberFormatC.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), 0, *VogelsNumberFormatC)
Else
If b = 0
VogelsNumberFormat_Zero(*VogelsNumberFormatC)
Else
If b < 0
b = -b
SetVogelsNumberFormatSign(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_NEGATIVE - GetVogelsNumberFormatSign(*VogelsNumberFormatA))
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
EndIf
NumID = 0
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
m.q + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID) * b
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, m % #VOGELS_NUMBER_FORMAT_MOD)
m / #VOGELS_NUMBER_FORMAT_MOD
Next
If m
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, m)
Else
NumID - 1
EndIf
SetVogelsNumberFormatLen(*VogelsNumberFormatC, NumID)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure Private_VogelsNumberFormat_DiW(*VogelsNumberFormatA.VogelsNumberFormat, b.l, *VogelsNumberFormatC.VogelsNumberFormat)
Protected NumID
Protected d.q, q.q
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), 0, *VogelsNumberFormatC)
Else
If b = 0
SetVogelsNumberFormatLen(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_UNDEFINED)
Else
If b < 0
b = -b
SetVogelsNumberFormatSign(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_NEGATIVE - GetVogelsNumberFormatSign(*VogelsNumberFormatA))
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
EndIf
For NumID = GetVogelsNumberFormatLen(*VogelsNumberFormatA) To 0 Step -1
d = d * #VOGELS_NUMBER_FORMAT_MOD + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
q = d / b
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, q)
d - q * b
Next
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Div(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
If GetVogelsNumberFormatLen(*VogelsNumberFormatB) = 0
If GetVogelsNumberFormatNum(*VogelsNumberFormatB, 0) = 0
SetVogelsNumberFormatLen(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_UNDEFINED)
Else
Private_VogelsNumberFormat_DiW(*VogelsNumberFormatA, GetVogelsNumberFormatNum(*VogelsNumberFormatB, 0), *VogelsNumberFormatC)
SetVogelsNumberFormatSign(*VogelsNumberFormatC, -(1 & (GetVogelsNumberFormatSign(*VogelsNumberFormatA) + GetVogelsNumberFormatSign(*VogelsNumberFormatB))))
EndIf
Else
If VogelsNumberFormat_GreaterThan(*VogelsNumberFormatB, *VogelsNumberFormatA, #True)
VogelsNumberFormat_Zero(*VogelsNumberFormatC)
Else
; Hmmm...
EndIf
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Add(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Protected n
Protected s
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB)
SetVogelsNumberFormatSign(*VogelsNumberFormatB, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
VogelsNumberFormat_Sub(*VogelsNumberFormatA, *VogelsNumberFormatB, *VogelsNumberFormatC)
Else
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < GetVogelsNumberFormatLen(*VogelsNumberFormatB)
Swap *VogelsNumberFormatA, *VogelsNumberFormatB
EndIf
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
s + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
If NumID <= GetVogelsNumberFormatLen(*VogelsNumberFormatB)
s + GetVogelsNumberFormatNum(*VogelsNumberFormatB, NumID)
EndIf
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s % #VOGELS_NUMBER_FORMAT_MOD)
s / #VOGELS_NUMBER_FORMAT_MOD
Next
NumID + 1
If s
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s)
Else
NumID - 1
EndIf
SetVogelsNumberFormatLen(*VogelsNumberFormatC, NumID)
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Sub(*VogelsNumberFormatA.VogelsNumberFormat, *VogelsNumberFormatB.VogelsNumberFormat, *VogelsNumberFormatC.VogelsNumberFormat)
Protected n
Protected s
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) < 0 Or GetVogelsNumberFormatLen(*VogelsNumberFormatB) < 0
Error = VogelsNumberFormat_Error(GetVogelsNumberFormatLen(*VogelsNumberFormatA), GetVogelsNumberFormatLen(*VogelsNumberFormatB), *VogelsNumberFormatC)
Else
If GetVogelsNumberFormatSign(*VogelsNumberFormatA) <> GetVogelsNumberFormatSign(*VogelsNumberFormatB)
SetVogelsNumberFormatSign(*VogelsNumberFormatB, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
VogelsNumberFormat_Add(*VogelsNumberFormatA, *VogelsNumberFormatB, *VogelsNumberFormatC)
Else
If VogelsNumberFormat_GreaterThan(*VogelsNumberFormatA, *VogelsNumberFormatB, #True)
SetVogelsNumberFormatSign(*VogelsNumberFormatC, GetVogelsNumberFormatSign(*VogelsNumberFormatA))
Else
Swap *VogelsNumberFormatA, *VogelsNumberFormatB
SetVogelsNumberFormatSign(*VogelsNumberFormatC, #VOGELS_NUMBER_FORMAT_NEGATIVE - GetVogelsNumberFormatSign(*VogelsNumberFormatA))
EndIf
For NumID = 0 To GetVogelsNumberFormatLen(*VogelsNumberFormatA)
s + GetVogelsNumberFormatNum(*VogelsNumberFormatA, NumID)
If NumID <= GetVogelsNumberFormatLen(*VogelsNumberFormatB)
s - GetVogelsNumberFormatNum(*VogelsNumberFormatB, NumID)
EndIf
If s < 0
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s + #VOGELS_NUMBER_FORMAT_MOD)
s = -1
Else
SetVogelsNumberFormatNum(*VogelsNumberFormatC, NumID, s)
s = 0
EndIf
Next
SetVogelsNumberFormatLen(*VogelsNumberFormatC, NumID)
VogelsNumberFormat_Normalize(*VogelsNumberFormatC)
EndIf
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Square(*VogelsNumberFormatA.VogelsNumberFormat)
If GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0
Error = VogelsNumberFormat_Mul(*VogelsNumberFormatA, *VogelsNumberFormatA, VNF_Cache_C.VogelsNumberFormat)
VogelsNumberFormat_Copy(VNF_Cache_C, *VogelsNumberFormatA)
ResetVogelsNumberFormat(VNF_Cache_C)
EndIf
ProcedureReturn Error
EndProcedure
Procedure VogelsNumberFormat_Pow(*VogelsNumberFormatA.VogelsNumberFormat, Exponent.l, *VogelsNumberFormatC.VogelsNumberFormat)
Protected z = 0, s, sign
If Exponent < 0
; a^b | b<0 not implemented for now...
VogelsNumberFormat_Error(#VOGELS_NUMBER_FORMAT_NOT_IMPLEMENTED, 0, *VogelsNumberFormatC)
ElseIf GetVogelsNumberFormatLen(*VogelsNumberFormatA) >= 0
VogelsNumberFormat_Copy(*VogelsNumberFormatA, VNF_Cache_A.VogelsNumberFormat)
String_To_VogelsNumberFormat(VNF_Cache_B.VogelsNumberFormat, "1")
If VogelsNumberFormat_Positive(*VogelsNumberFormatA) = #False
VogelsNumberFormat_Abs(VNF_Cache_A)
If Exponent & 1
SetVogelsNumberFormatSign(VNF_Cache_B, #VOGELS_NUMBER_FORMAT_NEGATIVE)
EndIf
EndIf
While Exponent > 0
s = 1 << z
If Exponent & s
VogelsNumberFormat_Mul(VNF_Cache_A, VNF_Cache_B, VNF_Cache_C.VogelsNumberFormat)
VogelsNumberFormat_Copy(VNF_Cache_C, VNF_Cache_B)
Exponent = Exponent - s
EndIf
If Exponent
VogelsNumberFormat_Square(VNF_Cache_A)
z = z + 1
EndIf
Wend
VogelsNumberFormat_Copy(VNF_Cache_B, *VogelsNumberFormatC)
EndIf
ResetVogelsNumberFormat(VNF_Cache_A)
ResetVogelsNumberFormat(VNF_Cache_B)
ResetVogelsNumberFormat(VNF_Cache_C)
EndProcedure
Procedure VogelsNumberFormat_Factorial(Value.l, *VogelsNumberFormatC.VogelsNumberFormat)
String_To_VogelsNumberFormat(VNF_Cache_B.VogelsNumberFormat, "1")
For Index = 2 To Value
String_To_VogelsNumberFormat(VNF_Cache_C.VogelsNumberFormat, Str(Index))
VogelsNumberFormat_Mul(VNF_Cache_B, VNF_Cache_C, VNF_Cache_R.VogelsNumberFormat)
VogelsNumberFormat_Copy(VNF_Cache_R, VNF_Cache_B)
Next
VogelsNumberFormat_Copy(VNF_Cache_B, *VogelsNumberFormatC)
ResetVogelsNumberFormat(VNF_Cache_B)
ResetVogelsNumberFormat(VNF_Cache_C)
ResetVogelsNumberFormat(VNF_Cache_R)
EndProcedure
Procedure VogelsNumberFormat_Random(*VogelsNumberFormatA.VogelsNumberFormat, MaximumDigitCount.l)
Max = Random(MaximumDigitCount)
For Index = 1 To Max
RandomNumber.s = RandomNumber + Str(Random(9))
Next
If Left(RandomNumber, 1) = "0"
RandomNumber = Right(RandomNumber, Len(RandomNumber) - 1)
EndIf
String_To_VogelsNumberFormat(*VogelsNumberFormatA, RandomNumber)
EndProcedure
Procedure ReadPreferenceVogelsNumberFormat(GroupName.s, *VogelsNumberFormatA.VogelsNumberFormat)
String_To_VogelsNumberFormat(*VogelsNumberFormatA, ReadPreferenceString(GroupName, VogelsNumberFormat_To_String(*VogelsNumberFormatA)))
EndProcedure
Procedure WritePreferenceVogelsNumberFormat(GroupName.s, *VogelsNumberFormatA.VogelsNumberFormat)
WritePreferenceString(GroupName, VogelsNumberFormat_To_String(*VogelsNumberFormatA))
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<<
; <<<<< !!! WARNING - THIS CODE SHOULD BE COMMENTED - WARNING !!! <<<<<
; <<<<< !!! WARNING - BEFORE THE FINAL COMPILATION. - WARNING !!! <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Procedure.s FormatInteger(Number.s)
; Format Integer created by Gnozal
NumberLen = Len(Number)
Start = NumberLen % 3
FormatedNumber.s = Left(Number, Start)
For i = Start + 1 To NumberLen - Start Step 3
FormatedNumber + " " + Mid(Number, i, 3)
Next
ProcedureReturn LTrim(FormatedNumber)
EndProcedure
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(MyNumber.VogelsNumberFormat, "00000000000000000000123456789987654321123456789987654321")
Debug VogelsNumberFormat_To_String(MyNumber)
VogelsNumberFormat_Normalize(MyNumber)
Debug VogelsNumberFormat_To_String(MyNumber)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(X.VogelsNumberFormat, "23456")
String_To_VogelsNumberFormat(Y.VogelsNumberFormat, "98765")
VogelsNumberFormat_Add(X, Y, Z.VogelsNumberFormat)
Debug VogelsNumberFormat_To_String(Z)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(Number1.VogelsNumberFormat, "12345678999999994012121212155454789921999")
String_To_VogelsNumberFormat(Number2.VogelsNumberFormat, "15906045674")
VogelsNumberFormat_Mul(Number1, Number2, Number3.VogelsNumberFormat)
Debug VogelsNumberFormat_To_String(Number1) + " * " + VogelsNumberFormat_To_String(Number2) + " = " + VogelsNumberFormat_To_String(Number3)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
String_To_VogelsNumberFormat(Number.VogelsNumberFormat, "100")
VogelsNumberFormat_Pow(Number, 100, Result.VogelsNumberFormat)
Debug VogelsNumberFormat_To_String(Result)
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
For Factorial = 50 To 100
VogelsNumberFormat_Factorial(Factorial, TestFactorial.VogelsNumberFormat)
Debug Str(Factorial) + "! = " + FormatInteger(VogelsNumberFormat_To_String(TestFactorial))
Next
Debug ""
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug ""
For RandomID = 0 To 5
VogelsNumberFormat_Random(TestRandom.VogelsNumberFormat, 25)
Debug FormatInteger(VogelsNumberFormat_To_String(TestRandom))
Next
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Code: Select all
Procedure.s FormatInteger(Number.s,Group.i=3)
; Format Integer created by Gnozal
NumberLen = Len(Number)
Start = NumberLen % Group
FormatedNumber.s = Left(Number, Start)
i=Start + 1
While i<=NumberLen - Start
FormatedNumber + " " + Mid(Number, i,Group)
i+Group
Wend
ProcedureReturn LTrim(FormatedNumber)
EndProcedure