Recent Posts

Pages: [1] 2 3 ... 10
1
General / Re: Calculating with big numbers
« Last post by Arnold on October 15, 2017, 09:32:16 AM »
Hey Charles,

you have already finished what I was about to do. But since I will never achieve your accuracy I will focus on your code. Will you work out the functions as a library? There are already many things possible, e.g.:

The idea to explore big numbers arose from Robbek's message:
http://www.oxygenbasic.org/forum/index.php?topic=1231.msg11994#msg11994

and this can be done easily with your functions:

Code: [Select]
...
print "fibonacci" cr
sa=0
sb=1
time1=GetTickCount()
for i=1 to 4000
  sr=add sa,sb
'  print i tab sr cr
  sa=sb
  sb=sr
next
i-=1 ' adjust i
time=(GetTickCount()-time1) / 1000
print "fibo " i " = " sr cr
printl "This took " time " Seconds" cr
...

With a modern pc this will take 0.0078 seconds or less and this is really fast if one takes into account that the code does not play with changing the bases and/or grouping the digits to integers.

I have not yet explored the functions intensively but I noticed you also added some code for negative numbers. Is it already possible to calculate 1-1000, or -100*1 or -2*-3 ? I was about to implement Karatsuba's method for multiplication, but I noticed that I will need to calculate negative interim results in some cirumstances.

Roland
2
General / Efficient Approximation
« Last post by Charles Pegge on October 15, 2017, 03:51:43 AM »
An old example revisited with some FPU assembler. Using the FPU stack is, in theory, more efficient than loading variables from RAM.

This algorithm is quite complicated but it is highly efficient and converges on the answer with very few iterations.

Code: [Select]

'SUCCESSIVE APPROXIMATION USING NEGATIVE FEEDBACK
'================================================

  uses console
  '
  macro ff(a)
  '==========
   '
   'NULL EXPRESSIONS
   '
   '0
   '1
   'a^5-2               'roots of 2
   '(a*a*a) + (a*a) -3 'compound roots
   'a*a*a-2            'cube root of 2
   abs (tan(a/4)-1)   'pi
   'abs((1/a)-a+1)     'phi
   'tan(rad(a))-2      'spherical angle of icosahedron facet edge
  end macro

  function approx(float e1,e2) as extended
  ========================================
  dim as double a,a1,a2,b1,b2,fbk
  dim as long i
  a1=e1      ' first estimate of answer
  a2=e2      ' second estimate of answer
  b1=ff(a1)  ' first result
  b2=ff(a2)  ' second result
  print i tab a2 cr
  do
    if i>=1000 then exit do 'restrict iterations
    if a1=a2 then exit do   'input precsion limit
    if b1=b2 then exit do   'feedback precision limit
    '
    'fbk=(a2-a1)/(b2-b1)    'feedback
    'a1=a2                  'new a1 input
    'a2=a2-b2*fbk           'new a2 input
    'b1=b2                  'new b1 output
      fld  qword a2
      fld  st0
      fld  st0
      fsub qword a1
      fld  qword b2
      fld st0
      fld st0
      fsub qword b1
      fxch st1
      fstp qword b1
      fdivp          'fbk
      fmulp          'qword b2
      fsubp          'qword a2
      fstp qword a2
      fstp qword a1
    b2=ff(a2)               'new b2 output
    i++
    '
    print i tab a2 cr
  end do
  return a2
  end function

'r=approx(-2,-1) ' lower est, upper est
r=approx(3.1414,3.1415) ' lower est, upper est
'print str(r)
waitkey
 
3
General / Re: Calculating with big numbers
« Last post by Charles Pegge on October 15, 2017, 02:09:36 AM »
First, the numbers are converted from ascii to binary by subtracting 48 from each digit. Then a lookup table is prepared with multiples of the divisor x1 x2 x3 .. x9. Then we are ready for the main algorithm.

Comparisons are made using the table values, and the selected table index becomes the value of the current digit. The selected number is then subtracted leaving a possible remainder. We then shift 1 place to the right for the next digit, and repeat the process until the right hand end is reached.

The devil is in the detail :)

Code: [Select]
  function div(string sa,sb) as string
  ====================================
  string a="0"+zerotrim(sa)
  int la=len a
  string b="0"+zerotrim(sb)
  int lb=len b
  tobin a : tobin b
  int lo=la-lb+1
  string o=nuls lo
  '
  'CREATE LOOKUP TABLE 1xB 2xB ..9xB
  indexbase 1
  string tbl[9]
  int i,j,k
  sbyte *ti,*tj
  tbl[1]=b : j=1
  for i=2 to 9
    tbl[i]=b
    @ti = strptr(tbl[i])+lb-1
    @tj = strptr(tbl[j])+lb-1
    cy=0
    for k=1 to lb 'add digits
      ti=ti+tj+cy
      if ti>=10 then ti-=10 : cy=1 else cy=0
      @ti-- : @tj--
    next
    j++
  next
  '
  sbyte aa at strptr(a)
  sbyte bb at strptr(b)
  sbyte oo at strptr(o)
  sbyte d,carry
  int i,j,k,c,cm
  sys pa=@aa
  for i = 1 to lo 'setting dividend digits
    c=9 'default digit
    for k=1 to 9
      cm=CompareMid(i,a,tbl[k]) 'lookup multiple of b
      if cm<0 then c=k-1 : exit for 'set digit
    next
    if c then 'perform subtraction
      @aa=pa+i+lb-2
      @bb=strptr(tbl[c])+lb-1
      cb=lb
      carry=0
      for j=1 to lb 'subtraction
        d=aa-bb-carry
        if d<0 then d+=10 : carry=1 else carry=0
        aa=d
        @bb-- : @aa--
      next 'next subtraction digit
    end if 'subtraction
    oo=c 'set dividend digit as subraction count
    @oo++
  next  'next dividend digit
  remainder=nullTrim a
  o=nulltrim o
  if not o then o=chr 0
  toasc o
  toasc remainder
  return o
  end function
  '

supporting functions
Code: [Select]
  macro tobin(s,  bb,le) {
  ========================
  int le=len s
  sbyte bb at strptr s
  while le
    bb-=48
    @bb++ : le--
  wend
  }
  macro toasc(s,  bb,le) {
  ========================
  int le=len s
  sbyte bb at strptr s
  while le
    bb+=48
    @bb++ : le--
  wend
  }

  function compareMid(int i, string a,b) as int
  =============================================
  i-- 'convert to base 0
  int la=len(a)-i
  int lb=len b
  byte aa at i+strptr a
  byte bb at strptr b
  if lb>la
    return -1
  else
    while lb
      if aa>bb then return 1
      if aa<bb then return -1
      lb-- : @aa++ : @bb++
    wend
  end if
  end function
  '
  function nullTrim(string a) as string
  =====================================
  byte aa at strptr a
  int la=len a
  int c=1
  while la
    if aa>0 then return mid a,c
    la-- : c++ : @aa++
  wend
  end function
  '
  function zeroTrim(string a) as string
  =====================================
  byte aa at strptr a
  int la=len a
  int c=1
  while la
    if aa>48 then return mid a,c
    la-- : c++ : @aa++
  wend
  end function

4
Open Forum / Re: ThinBasic
« Last post by Charles Pegge on October 15, 2017, 01:15:47 AM »
Hi Kuron,

No recent problems from here (UK) -- using FireFox

http://www.thinbasic.com/community/forum.php
5
Open Forum / ThinBasic
« Last post by Kuron on October 15, 2017, 12:19:20 AM »
For about a week, I can't get into ThinBasic.  I keep getting the following message.  The only site I am having issues with.  Anybody else having this issue, or is it just me?

6
DLLC / Re: DLLC Development
« Last post by John on October 14, 2017, 11:32:21 PM »
One of my most favorite features of Script BASIC is its array (matrix) functionality. You don't have to define or dimension anything and there are no practical limits on indices. (associative, indexed or a combination of both)

Code: Script BASIC
  1. ' Test  Associative Array by Index
  2.  
  3. obj{"Name"}{"Value"} = undef
  4. obj{"Name"}{"Product"} = "ALL"
  5. obj{"Name"}{"Required"} = TRUE
  6. obj{"ID"}{"Value"} = undef
  7. obj{"ID"}{"Product"} = "SOME"
  8. obj{"ID"}{"Required"} = FALSE
  9.  
  10. this{"Extension"}{"Value"} = "Default"
  11. this{"Extension"}{"Product"} = "FEW"
  12. this{"Extension"}{"Required"} = "MAYBE"
  13.  
  14. obj{"Version"} = this{"Extension"}
  15.  
  16. FOR o = 0 TO UBOUND(obj) STEP 2
  17.   PRINT obj[o],"\n"
  18.   FOR p = 0 TO UBOUND(obj[o + 1]) STEP 2
  19.     PRINT obj[o + 1, p]," - ",obj[o + 1, p + 1],"\n"
  20.   NEXT
  21. NEXT
  22.  
  23. PRINT "-------------------------------","\n"
  24.  
  25. PRINT obj[0],"\n"
  26. PRINT obj[1,0]," - ",obj[1,1],"\n"
  27. PRINT obj[1,2]," - ",obj[1,3],"\n"
  28. PRINT obj[1,4]," - ",obj[1,5],"\n"
  29. PRINT obj[2],"\n"
  30. PRINT obj[3,0]," - ",obj[3,1],"\n"
  31. PRINT obj[3,2]," - ",obj[3,3],"\n"
  32. PRINT obj[3,4]," - ",obj[3,5],"\n"
  33. PRINT obj[4],"\n"
  34. PRINT obj[5,0]," - ",obj[5,1],"\n"
  35. PRINT obj[5,2]," - ",obj[5,3],"\n"
  36. PRINT obj[5,4]," - ",obj[5,5],"\n"
  37.  
  38.  
  39. PRINT "-------------------------------","\n"
  40.  
  41. PRINT obj[2],"\n"
  42. FOR z = 0 TO UBOUND(obj{"ID"}) STEP 2
  43.   PRINT obj{"ID"}[z]," - ",obj{"ID"}[z + 1],"\n"
  44. NEXT
  45.  


Name
Value - undef
Product - ALL
Required - -1
ID
Value - undef
Product - SOME
Required - 0
Version
Value - Default
Product - FEW
Required - MAYBE
-------------------------------
Name
Value - undef
Product - ALL
Required - -1
ID
Value - undef
Product - SOME
Required - 0
Version
Value - Default
Product - FEW
Required - MAYBE
-------------------------------
ID
Value - undef
Product - SOME
Required - 0

7
DLLC / Re: DLLC Development
« Last post by John on October 12, 2017, 10:25:54 PM »
It seems rather easy to use .NET components with COM. Here is a C# example using the .NET Date Picker and made COM aware.

Creating COM Objects with Visual Basic.NET



Code: Script BASIC
  1. import com.inc
  2.  
  3. cs = CreateObject("Sample.Sample")
  4. d = CallByName(cs, "GetDate")
  5. print "User Selected date: ", d
  6.  


C:\sb22_32\sbvb-2>scriba cs_date.sb
User Selected date: 6/25/2014
C:\sb22_32\sbvb-2>


Hard to believe it has been over 3 years since Dave originally wrote the example. I miss Dave a lot.
8
General / Re: Calculating with big numbers
« Last post by Charles Pegge on October 11, 2017, 10:49:20 PM »
Hi Roland,

I'm glad you found it helpful.

There are lots of ways to make it go even faster. For instance, working with base10000 digits instead of base10 digits. In theory, this would give you a 16x boost in speed.

I've also got an algorithm for big number division, something I have always wanted to do. It is based on a series of shifting subtractions, similar to school-teacher punishment long division :)

Will post it later.

9
General / Re: Calculating with big numbers
« Last post by Arnold on October 10, 2017, 11:29:53 PM »
Hi Charles,

this is really impressive. Your modifications for str_mult reduced the execution time by almost 99% (!). I also get a correct result for 5**262144. This example demonstrates again how important it is to deal with strings efficiently in time-consuming tasks and I will study the code very carefully. I learned about a new keyword: stringbytes; I already missed this functionality sometimes.

It is also remarkable that the function str_mult runs almost as fast as the multiply function in \examples\math\MulHuge.o2bas which is realized with assembler statements. This is another proof of OxygenBasic's speed.

Thank you again for your help. It will help me to understand some more examples where this approach is applied too.

Roland
10
DLLC / Re: DLLC Development
« Last post by John on October 10, 2017, 10:15:18 AM »
Quote
Nonetheless I would like to take low-level COM support a bit further, looking at DirectX as a model. I have already done some fine tuning to Oxygen, while investigating Josť's port of DirectX9.

That is great news Charles. I feel Dave's VB6/COM/OLE extension module will handle the high level COM interfaces targeted at Microsoft Office and other main stream (QuickBooks Desktop) like interfaces.

Pages: [1] 2 3 ... 10