Squares

General FreeBASIC programming questions.
Richard
Posts: 2948
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Postby Richard » Aug 25, 2018 5:18

@Albert.
First demonstrate that your algorithm works for 10, 100 and 1000 decimal digit numbers when represented in ASCII base two. I can then accurately predict what your million decimal digit time will be.
If you can do a 10 x 10 decimal digit multiply in 100 microsec, then 100 x 100 will only take 10 milliseconds, 1k x 1k digits will take 1 second. 10k x 10k will take 100 sec, 100k x 100k will take 10ksec = 166.7 minutes = 2.78 hours. 1M x 1M will take about 11.5 days.

Remember that Log₂(10) = 3.322 so a 1 Mbyte decimal ASCII string will become a 3.322 Mbyte binary ASCII string. If you try to multiply a pair of million digit decimal numbers, represented in ASCII binary, then I doubt you will complete the calculation in less than a week. Now, stop complaining about the speed of my conversion code, prove my prediction of 1 week wrong by getting times for 10, 100 and 1000 digits.
jj2007
Posts: 1203
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Squares

Postby jj2007 » Aug 25, 2018 7:49

albert wrote:I measured the speed of both the "number creator" and the "conversion"..
Can you show me where you did that? This part clearly measures the speed of string concatenation:

Code: Select all

   Dim as string res=""
   time1 = timer
        For a as longint = 1 To 10000
            res+=str(int(rnd*10))
        Next
    time2 = timer
albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Aug 25, 2018 16:29

@jj2007

Heres the code i posted to you a page back..

Theres two sets of timers, 1 for building the number and 1 for the conversion.


Code: Select all

#include "Windows.bi"

 Function base2(DecimalNumber As String) As String
            Dim As String starter=DecimalNumber,ans,m,b=string(4*len(DecimalNumber),32)
             static as byte a(48 to 57)={0,10,0,10,0,10,0,10,0,10}
            Dim As long c,lens
            #macro reverse(s)
                lens=Len(s)
                For n As Integer=0 To Int((lens-1)/2):Swap s[n],s[lens-1-n]:Next
                #endmacro
                #macro div2(s,m,c)
                c=0:ans=s
                For z As long=0 To Len(s)-1
                     ans[z]=  (c+s[z]) shr 1 +24
                      c=a(s[z])
                Next z
                m= Ltrim(ans,"0")
                #endmacro
                dim as long idx
                Do
                    div2(starter,m,c)
                    b[idx]=c\10+48
                    starter=m
                    idx+=1
                Loop Until m="1" orelse m=""
                b=rtrim(b)
                reverse(b)
                b=Str(m)+b
                Return b
         End Function

screen 19

   Dim as double time1,time2
   Dim as string res=""
   
   time1 = timer
        For a as longint = 1 To 10000
            res+=str(int(rnd*10))
        Next
    time2 = timer
   
    print time2-time1 , "time to build number."
   
    time1= timer
       dim as string ans = base2(res)
    time2 = timer
   
   print time2 - time1 , "time to conveert to base2"
   
   sleep()
   
   end
   

albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Aug 25, 2018 19:11

@Richard

I converted your base10_to_2() to use pointers , it only speeds it up by a second or so on 1 million.
I've got to convert the acc( i ) to use a pointer into the acc( ) array..
I think array access takes 16 clocks per access.. i think an array( pointer ) takes 1 clock (not sure) ??

Code: Select all

'=======================================================================
' Convert base two ASCII binary string to base ten ASCII decimal string
'=======================================================================
Function base_2_to_10( Byref b As String ) As String    ' b may be lengthened
    ' lengthen input string by up to 28 zero bits to make 29 bit blocks
    Dim As Integer n = Len( b ) Mod 29
    If n Then b = String( 29 - n, "0" ) + b
    n = Len( b ) \ 29  ' number of input blocks
    Dim As Ulong acc( 0 To n )  ' accumulator array
    ' convert blocks of 9 digits to binary in 32 bit Ulong
    Dim As Ulongint product, carry  ' 64 bit Unsigned Integer
    Dim As Integer i, j, k = 1      ' loop counters
    For j = 1 To Len( b ) Step 29   ' the blocks to convert
        carry = Valulng( "&b" + Mid( b, j, 29 ) ) ' value of 29 bit block
        For i = 0 To k  ' Multiply Accumulate,   2^29 = 536870912
            product = ( Culngint( acc( i ) ) * 536870912ull ) + carry
            acc( i ) = product Mod 1000000000ull    ' sum is low part
            carry = product \ 1000000000ull     ' carry is the high part
        Next i
        If carry Then   ' extend accumulator by one element when needed
            k += 1
            acc( k ) = carry
        End If
    Next j  ' accumulator now contains result blocks of base 1 billion
    ' unpack and return acc as decimal ASCII string
    Dim As String txt
    For i = n To 0 Step -1
        txt += Right( "000000000" + Str( acc( i ) ), 9 )
    Next i
    Return Ltrim( txt, "0" )
End Function

'=======================================================================
' Convert base ten ASCII decimal string to base two ASCII binary string
'=======================================================================
Function base_10_to_2( Byref d As String ) As String  ' d may be lengthened
    ' lengthen input string by up to 8 digits to make 9 digit blocks
    Dim As Integer n = Len( d ) Mod 9
    If n Then d = String( 9 - n, "0" ) + d
    n = Len( d ) \ 9  ' number of input blocks
    Dim As Ulong acc( 0 To n )  ' the accumulator array
    ' convert blocks of 9 digits to binary in 32 bit Ulong
    Dim As Ulongint product, carry  ' 64 bit Unsigned Integer
    Dim As Integer i, j, k = 1      ' loop counters
   
    '================================================
    'begin alberts additons
    '================================================
    dim as string number = d
    dim as string str1
    dim as longint dec1
    do
        str1 = str(len(number)/9)
        dec1 = instr(1,str1,".")
        if dec1 <> 0 then number = "0" + number
    loop until dec1 = 0
    'convert the numeric strings to use pointers
    'convert number1
    dim as string n1 = string(len(number)*8,chr(0))
    dim as ulongint ptr ulp1
    ulp1 = cptr(ulongint ptr,strptr(n1))
    dim as longint val1
    dim as longint len_1 = 0
    dim as uinteger a
    for a = 0 to len(number)-1 step 9
        val1  = (number[a+0]-48)*100000000ull
        val1+= (number[a+1]-48)*10000000ull
        val1+= (number[a+2]-48)*1000000ull
        val1+= (number[a+3]-48)*100000ull
        val1+= (number[a+4]-48)*10000ull
        val1+= (number[a+5]-48)*1000ull
        val1+= (number[a+6]-48)*100ull
        val1+= (number[a+7]-48)*10ull
        val1+= (number[a+8]-48)*1
        *ulp1 = val1
        ulp1+=1
        len_1+=8
    next
    number = left(n1,len_1)
    n1=""
    '================================================
    'end alberts additons
    '================================================
    ulp1 = cptr(ulongint ptr,strptr(number))
    For j = 1 To Len(number)  Step 8     ' the blocks to convert
        'carry = Valulng( Mid( d, j, 9 ) ) ' get value of 9 digit block
        carry = *ulp1
        ulp1+=1
        For i = 0 To k  ' Multiply Accumulate
            product = ( culngint( acc( i ) ) * 1000000000ull ) + carry
            acc( i ) = product And &hFFFFFFFFull ' sum is low order 32 bits
            carry = product shr 32 ' carry is the high order 32 bits
        Next i
        If carry Then   ' extend accumulator by one element when needed
            k+=1
            acc( k ) = carry
        End If
    Next j  ' accumulator now contains result in packed binary
    ' unpack and return it as binary ASCII string
    Dim As String txt
    For i = n To 0 Step -1
        txt += Bin( acc( i ), 32 )
    Next i
    Return Ltrim( txt, "0" )
End Function

'=======================================================================

screen 19

dim as double time1 , time2

do
     dim as string num=""
     for a as longint = 1 to 100000 step 1
         num+=str( int(rnd*10) )
    next
    if left(num,1) = "0" then mid(num,1,1) = str(int(rnd*9)+1)
   
    time1 = timer
        dim as string binari = base_10_to_2( num )
        binari = ltrim(binari,"0")
    time2 = timer
   
    'dim as string base10 = binari
    'dim as string decimal = base_2_to_10( binari )
   
    print ltrim( num, "0")
    'print decimal
    print bin(val(num))
    print binari
    print
    print "len = " ; len(binari)
    print
    print "Time = " ; time2 - time1
   
    if inkey = " " then sleep
   
loop until inkey = chr(27)

sleep
end

Richard
Posts: 2948
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Postby Richard » Aug 25, 2018 20:53

Albert wrote:I converted your base10_to_2() to use pointers , it only speeds it up by a second or so on 1 million.
I've got to convert the acc( i ) to use a pointer into the acc( ) array..
I think array access takes 16 clocks per access.. i think an array( pointer ) takes 1 clock (not sure) ??

I am convinced you are wasting your time. My code works reliably as it is, and it is easy to understand and maintain. The access time into an array depends on the level of index bound checking you do. During development you should use the maximum possible -exx checking. If that takes 16 cycles, then it is worth every nanosecond required.

Your binary ASCII multiply code does not work at all because you have not written it, and you probably never will.
If you did manage to get your code to work, it would take over a week to multiply a pair million digit numbers.

Meanwhile the Acc() inside my converters are packed binary, which is ideal for doing fast multiplies. A million by million digit multiply takes less than 10 minutes when packed, compared with your ASCII binary predicted to be one week. By avoiding binary ASCII, I can out-perform your code by a factor of more than one thousand.
jj2007
Posts: 1203
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Squares

Postby jj2007 » Aug 25, 2018 23:23

albert wrote:Theres two sets of timers, 1 for building the number and 1 for the conversion.
OK, I see, thanks. Do you explain somewhere the logic and math of this exercise (we are at page 399 of this thread...)?

For example,

Code: Select all

        For a as longint = 1 To 9
            res+=str(int(rnd*10))
        Next
produces the number 335766299, which gets translated to 10100000000110110001100011011. So far, so good. Is it correct that you apply some BigNum logic to extend this to numbers of any bitness? If yes, for what purpose?
albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Aug 26, 2018 2:18

@Richard

I converted your code to use pointers...
It's sped up using Geany IDE with build command ( -gen GCC -w all -O 3 "%f" )

Takes 15.?? seconds to convert 1,000,000 digits decimal to binary.
I got to find some more shortcuts.

Code: Select all

'=======================================================================
' Convert base two ASCII binary string to base ten ASCII decimal string
'=======================================================================
Function base_2_to_10( Byref b As String ) As String    ' b may be lengthened
    ' lengthen input string by up to 28 zero bits to make 29 bit blocks
    Dim As Integer n = Len( b ) Mod 29
    If n Then b = String( 29 - n, "0" ) + b
    n = Len( b ) \ 29  ' number of input blocks
    Dim As Ulong acc( 0 To n )  ' accumulator array
    ' convert blocks of 9 digits to binary in 32 bit Ulong
    Dim As Ulongint product, carry  ' 64 bit Unsigned Integer
    Dim As Integer i, j, k = 1      ' loop counters
    For j = 1 To Len( b ) Step 29   ' the blocks to convert
        carry = Valulng( "&b" + Mid( b, j, 29 ) ) ' value of 29 bit block
        For i = 0 To k  ' Multiply Accumulate,   2^29 = 536870912
            product = ( Culngint( acc( i ) ) * 536870912ull ) + carry
            acc( i ) = product Mod 1000000000ull    ' sum is low part
            carry = product \ 1000000000ull     ' carry is the high part
        Next i
        If carry Then   ' extend accumulator by one element when needed
            k += 1
            acc( k ) = carry
        End If
    Next j  ' accumulator now contains result blocks of base 1 billion
    ' unpack and return acc as decimal ASCII string
    Dim As String txt
    For i = n To 0 Step -1
        txt += Right( "000000000" + Str( acc( i ) ), 9 )
    Next i
    Return Ltrim( txt, "0" )
End Function

'=======================================================================
' Convert base ten ASCII decimal string to base two ASCII binary string
'=======================================================================
Function base_10_to_2( Byref d As String ) As String  ' d may be lengthened
    '================================================
    'begin alberts additons
    '================================================
    dim as string number = d
    dim as string str1
    dim as longint dec1
    do
        str1 = str( len(number) / 9 )
        dec1 = instr(1,str1,".")
        if dec1 <> 0 then number = "0" + number
    loop until dec1 = 0
    'convert the numeric strings to use pointers
    'convert number1
    dim as string n1 = string(len(number)*8,chr(0))
    dim as ulongint ptr ulp1
    ulp1 = cptr(ulongint ptr,strptr(n1))
    dim as longint val1
    dim as longint len_1 = 0
    dim as uinteger a
    for a = 0 to len(number)-1 step 9
        val1  = (number[a+0]-48)*100000000ull
        val1+= (number[a+1]-48)*10000000ull
        val1+= (number[a+2]-48)*1000000ull
        val1+= (number[a+3]-48)*100000ull
        val1+= (number[a+4]-48)*10000ull
        val1+= (number[a+5]-48)*1000ull
        val1+= (number[a+6]-48)*100ull
        val1+= (number[a+7]-48)*10ull
        val1+= (number[a+8]-48)*1
        *ulp1 = val1
        ulp1+=1
        len_1+=8
    next
    number = left(n1,len_1)
    n1=""
    '================================================
    'end alberts additons
    '================================================
    Dim As ulongint acc( 0 To len(number) \ 8 )  ' the accumulator array
    Dim As Ulongint product, carry  ' 64 bit Unsigned Integer
    Dim As Integer k = 1      ' loop counters
    dim as ulongint ptr ulp2
    ulp1 = cptr(ulongint ptr,strptr(number))
    For j as longint = 1 To Len(number)  Step 8     ' the blocks to convert
        'carry = Valulng( Mid( d, j, 9 ) ) ' get value of 9 digit block
        carry = *ulp1
        ulp1+=1
        ulp2 = cptr( ulongint ptr , varptr( acc(0) ) )
        For i as longint = 0 To k ' Multiply Accumulate
            product = culngint( *ulp2  * 1000000000ull ) + carry
            *ulp2 = product and 4294967295 ' sum is low order 32 bits
            carry = product shr 32 ' carry is the high order 32 bits
            ulp2+=1
        Next i
        If carry Then   ' extend accumulator by one element when needed
            k+=1
            *ulp2 = carry
        End If
    Next j  ' accumulator now contains result in packed binary
    ' unpack and return it as binary ASCII string
    Dim As String txt
    For i as longint = k to lbound(acc) Step -1
        txt+= Bin( acc(i) ,32 )
    Next i
    Return ltrim( txt , "0")
End Function

'=======================================================================
'Dodicats base2()
'=======================================================================
Function base2(DecimalNumber As String) As String
    Dim As String starter = DecimalNumber , ans , m , b = ""
    static as byte a(48 to 57) = {0,10,0,10,0,10,0,10,0,10}
    Dim As long c
        #macro div2(s,m,c)
        c = 0
        ans = s
        For z As long = 0 To Len(s)-1 step 1
            ans[z] = ( (c + s[z] ) shr 1 + 24 )
            c = a( s[z] )
        Next z
        m = Ltrim(ans,"0")
        #endmacro
        Do
            div2(starter,m,c)
            b = str( c \ 10 ) + b
            starter = m
        Loop Until m = ""
        b = rtrim(b)
        Return b
End Function     



screen 19

dim as double time1 , time2

do
     dim as string num=""
     for a as longint = 1 to 1000000  step 1
         num+=str( int(rnd*10) )
    next
    if left(num,1) = "0" then mid(num,1,1) = str(int(rnd*9)+1)
   
    dim as string bins ' = base2(num)
   
    time1 = timer
        dim as string binari = base_10_to_2( num )
    time2 = timer
   
    'dim as string base10 = binari
    'dim as string decimal = base_2_to_10( binari )
   
    print ltrim( num, "0")
    'print decimal
    print bins , len(bins)
    print
    print binari , len(binari)
    print
    print "Time = " ; time2 - time1
   
    if inkey = " " then sleep
   
loop until inkey = chr(27)

sleep
end

Richard
Posts: 2948
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Postby Richard » Aug 26, 2018 2:32

@Albert. Why do you need to find more shortcuts ?
What is 15 seconds when your multiply will take a week.
albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Aug 26, 2018 2:50

@Richard

1,000,000 digits decimal converts to 3,300,000 binary
3,300,000 / 32 = 100,000 multiplies.

1,000,000 / 7 = 100,000 multiplies..

So it should be the same or faster ( i hope. ) than my fastest multiply..
Richard
Posts: 2948
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Postby Richard » Aug 26, 2018 5:04

I don't think you know what you are doing. Why would you need ASCII binary, if not to delay the process? When you multiply 3.3 Mbits by 3.3 Mbits in ASCII it requires 10,890,000,000,000 partial product bits go into a massive Wallace Tree. https://en.wikipedia.org/wiki/Wallace_tree

Log₁₀( 2 ³² ) = 9.633 decimal digits per 32 bit block. 1 Mdigits / 9.633 = 103,810 blocks of 32 bits.
A 1 Mdigit × 1 Mdigit will therefore generate 103,810 ² = 10,776,568,620 partial products, each of 64 bits.
They will all have to be accumulated and carry propagated. That is how my BigInt overlay code did it.
albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Sep 06, 2018 2:10

@Richard
@Dodicat

Here's my latest attempt at a speedy multiplier...

Code: Select all


screen 19

do
   
    dim as ulongint n1 = int(rnd*99)+1
    dim as ulongint n2 = int(rnd*99)+1
   
    if n2 > n1 then swap n1,n2
   
   
    dim as ulongint ans2 = (n1+1) * (n2-1) + ( ((n1+1)-(n2-1)) -1 )
   
    dim as ulongint ans3 = (n1+2) * (n2-2) + ( ((n1+2)-(n2-2)) *2 - 4 )
   
    dim as ulongint ans4 = (n1+3) * (n2-3) + ( ((n1+3)-(n2-3)) *3 - 9 )
   
    dim as ulongint ans5 = (n1+4) * (n2-4) + ( ((n1+4)-(n2-4)) *4 - 16 )
   
    dim as ulongint ans6 = (n1+9) * (n2-9) + ( ((n1+9)-(n2-9)) *9 - 81 )
   
    print
    print "n1  = " ; n1
    print "n2  = " ; n2
    print
    print "ans  = " ; n1*n2
    print "ans2 = " ; ans2
    print "ans3 = " ; ans3
    print "ans4 = " ; ans4
    print "ans5 = " ; ans5
    print
    print "ans6 = " ; ans6
   
   
    sleep
   
    if inkey = chr(27) then exit do
   
loop

sleep
end



My favorite time of day 7:34 ( heaven dirty whore )
dodicat
Posts: 5880
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Squares

Postby dodicat » Sep 06, 2018 13:30

Hi Albert.
You express the same thing each way.
VIZ:

Code: Select all


screen 12,32

dim as long y=140
#define ln(a,c) line(a,y)-(a-20,y+30),c

print "(n1+k) * (n2-k) + ((n1+k)-(n2-k))*k  -k*k"

locate 5
print " =  n1*n2 -n1*k +n2*k -k*k  +(n1+k-n2+k)*k  -k*k"

locate 10           
print " =  n1*n2 -n1*k +n2*k -k*k  +n1*k + k*k -n2*k  +k*k -k*k"
ln(105,4):ln(250,4)
ln(159,2):ln(350,2)
ln(200,7):ln(310,7)
ln(400,5):ln(440,5)

locate 15
print " = n1*n2"
sleep 


Here is similar to your ulong, destined to be a pointer.
(For jump nine people)
Please wait for the 50 cycles.

Code: Select all

screen 19
function ValulngMid(num as string, start as long=1, length as long = 0) as ulong
    if start<=0 then start=1
    dim as long L=len(num)
  if  start+length > L-1 then length = (L-start)+1
  dim as ulong  d = 1, ans
  for i as long = length-1+start-1 to start-1 step -1
    ans += (num[i]-48)*d
    d =d Shl 3+d Shl 1  ' *= 10
  next
  return ans
end function

 dim as string s=""
     for a as longint = 1 to 1000000  step 1
         s+=str( int(rnd*10) )
    next
if left(s,1) = "0" then mid(s,1,1) = str(int(rnd*9)+1)


dim as long start=100000
const length=9
dim as double t,t2,tot1,tot2

for z as long=1 to 50
t=timer
dim as ulongint u
for n as long=1 to 1000000
u= valulngmid(s,start,length)
next
t2=timer
tot1+=t2-t
print t2-t,u,"function"
sleep 50
t=timer

for n as long=1 to 1000000
u=  valulng(mid(s,start,length))
next
t2=timer
tot2+=t2-t
print t2-t,u,"valulnint"
windowtitle  str(z) + " of " + "50"
print
next z

print
print tot1,"total time for function"
print tot2,"total time for valulng"
sleep 
albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Sep 06, 2018 23:41

@Dodicat

I was trying to take baby steps to derive a formula.

like 1234 * 5678 , (1234 + 678) * 5000 and then figure the missing value needed to make the multiply the right answer.

Code: Select all


screen 19

do
   
    dim as string num1
    for a as longint = 1 to 2
        num1+= str(int(rnd*10))
    next
    if left(num1,1) = "0" then mid(num1,1,1) = str(int(rnd*9)+1)
   
    dim as string num2
    for a as longint = 1 to 2
        num2+= str(int(rnd*10))
    next
    if left(num2,1) = "0" then mid(num2,1,1) = str(int(rnd*9)+1)
   
    if num2 > num1 then swap num1,num2
   
    dim as ulongint number1 =  val(num1) + val( mid(num2,2) )
    dim as ulongint number2 =  val( left(num2,1) + string(len(num2)-1,"0") )
   
    dim as ulongint ans7 = ( number1 * number2 )
       
    print
    print "n1  = " ; num1
    print "n2  = " ; num2
    print
    print number1 , number2
   
    print "ans  = " ; val(num1) * val(num2)
    print "ans7 = " ; ans7 , (val(num1)*val(num2)) - ans7
   
   
    sleep
   
    if inkey = chr(27) then exit do
   
loop

sleep
end

badidea
Posts: 1414
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Squares

Postby badidea » Sep 07, 2018 23:54

Sorry to interrupt to heavy calculations, but I have some squares to post in Squares :-)

Code: Select all

#include once "fbgfx.bi"

type xy_long
   dim as long x, y
end type

operator +(p1 as xy_long, p2 as xy_long) as xy_long
   return type(p1.x + p2.x, p1.y + p2.y)
end operator

union rgba_union
   value as ulong
   type
      b as ubyte
      g as ubyte
      r as ubyte
      a as ubyte
   end type
end union

'-------------------------------------------------------------------------------

type graphics_type ' pretty dumb graphics class
   private:
      dim as fb.Image ptr pFbImg
   public:
      dim as long w, h 'size
      declare constructor(w as long, h as long)
      declare sub activate()
      declare sub clearScreen()
      declare sub dimScreen(dimFactor as single) '0...1
end type

constructor graphics_type(w as long, h as long)
   this.w = w : this.h = h
end constructor

sub graphics_type.activate()
   screenres w, h, 32
   pFbImg = ImageCreate(w, h)
end sub

sub graphics_type.clearScreen()
   line(0, 0)-(w - 1, h - 1), &h00000000, bf
end sub

'todo: work directly with screenbuffer
sub graphics_type.dimScreen(dimFactor as single)
   dim as integer pitch, xi, yi
   dim as any ptr pPixels
   dim as rgba_union ptr pRow
   get (0, 0)-(w - 1, h - 1), pFbImg
   if imageinfo(pFbImg, , , , pitch, pPixels) <> 0 then exit sub
   if pPixels = 0 then exit sub
   for yi = 0 to h-1
      pRow = pPixels + yi * pitch
      for xi = 0 to w-1
         pRow[xi].r *= dimFactor
         pRow[xi].g *= dimFactor
         pRow[xi].b *= dimFactor
      next
   next
   put (0, 0), pFbImg, pset
end sub

'-------------------------------------------------------------------------------

type box_type 'Axis Aligned (minimum) Bounding Box
   public:
      dim as long x, y, w, h 'center position and size
      dim as ulong c 'color
      declare constructor()
      declare constructor(x as long, y as long, w as long, h as long, c as ulong)
      declare sub draw(solid as boolean)
      declare function left() as long
      declare function right() as long
      declare function up() as long
      declare function down() as long
end type

constructor box_type()
end constructor

constructor box_type(x as long, y as long, w as long, h as long, c as ulong)
   this.x = x : this.y = y
   this.w = w : this.h = h
   this.c = c
end constructor

sub box_type.draw(solid as boolean = false)
   if solid = true then
      line(x - w \ 2, y - h \ 2)-step(w - 1, h -1), c, bf
   else
      line(x - w \ 2, y - h \ 2)-step(w - 1, h -1), c, b
   end if
end sub

function box_type.left() as long
   return x - w \ 2
end function

function box_type.right() as long
   return x + w \ 2
end function

function box_type.up() as long
   return y - h \ 2
end function

function box_type.down() as long
   return y + h \ 2
end function

'-------------------------------------------------------------------------------

var graphics = graphics_type(800, 600)
graphics.activate()

const as integer NUM_BOX = 50
dim as box_type box(NUM_BOX-1)
'box(0) = box_type(150, 100, 50, 30, &h00ff00ff)
'box(1) = box_type(650, 350, 80, 120, &h00ffff00)

dim as xy_long vBox(NUM_BOX-1)
'vBox(0) = type(+5, +3)
'vBox(1) = type(+2, +4)

dim as integer i, x, y, w, h, vx, vy
dim as ulong c

randomize timer
for i = 0 to NUM_BOX-1
   w = int(rnd * 90 + 10)
   h = int(rnd * 90 + 10)
   x = int(rnd * (graphics.w - 110) + 50)
   y = int(rnd * (graphics.h - 110) + 50)
   c = int(rnd * &h00ffffff)
   box(i) = box_type(x, y, w, h, c)
   vx = (int(rnd * 2) * 2 - 1) * (int(rnd * 1) + 1)
   vy = (int(rnd * 2) * 2 - 1) * (int(rnd * 1) + 1)
   vBox(i) = type(vx, vy)
next

while inkey <> chr(27)
   for i = 0 to NUM_BOX-1
      if (box(i).left + vBox(i).x < 0) or (box(i).right + vBox(i).x > graphics.w - 1) then
         vBox(i).x = -vBox(i).x
      end if
      box(i).x += vBox(i).x
      if (box(i).up + vBox(i).y < 0) or (box(i).down + vBox(i).y > graphics.h - 1) then
         vBox(i).y = -vBox(i).y
      end if
      box(i).y += vBox(i).y
   next
   
   screenlock
   'graphics.clearScreen
   graphics.dimScreen(0.95)
   for i = 0 to NUM_BOX-1
      box(i).draw(0)
   next
   screenunlock
   sleep 15
wend
albert
Posts: 4914
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Postby albert » Sep 08, 2018 0:31

I've got a formula figured out...I got to go over it some more , making sure i'm not stupid!!
It seems to work for all digit sizes 2 to 8

I just kept blindly typing in stuff , til i got it to work?? It works.. Now to convert it to strings..

Code: Select all


screen 19

do
   
    dim as string num1
    for a as longint = 1 to 4
        num1+= str(int(rnd*10))
    next
    if left(num1,1) = "0" then mid(num1,1,1) = str(int(rnd*9)+1)
   
    dim as string num2
    for a as longint = 1 to 4
        num2+= str(int(rnd*10))
    next
    if left(num2,1) = "0" then mid(num2,1,1) = str(int(rnd*9)+1)
   
    if num2 > num1 then swap num1,num2
   
    dim as ulongint number1 =  val(num1) + val( mid(num2,2) )
    dim as ulongint number2 =  val( left(num2,1) + string(len(num2)-1,"0") )
   
    dim as ulongint ans7 = ( number1 * number2 ) + ( val(num1) * val(right(num2,len(num2)-1)) ) - ( val(num2)  * val(right(num2,len(num2)-1)) ) + (val(right(num2,len(num2)-1))^2)
       
    print
    print "n1  = " ; num1
    print "n2  = " ; num2
    print
    print "ans   = " ; val(num1) * val(num2)
    print "my ans = " ; ans7 , (val(num1)*val(num2)) - ans7
   
    sleep
   
    if inkey = chr(27) then exit do
   
loop

sleep
end


Return to “General”

Who is online

Users browsing this forum: No registered users and 5 guests