Another javascript porting

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Another javascript porting

#1 Post by einstein1969 » 16 Nov 2015 10:10

Hi to all,

I want to do a porting from a hmtl javascript to DOS for probe/develop/speedup some math function.

I have choice this for the SQRT function, but there is a POW too (only a CUBE for now).

If you want you can also see it as an exercise or contest.

Other versions are also accepted: using hybrid dos/JS/VB, powershell, mshta, ...

but must not miss DOS BATCH only version. 8)

EDIT:
main article

Einstein1969

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Another javascript porting

#2 Post by einstein1969 » 19 Nov 2015 10:37

Ok. I start and i found the first barrier.

The big problem is the POW function or in this subcase the CUBE function.

The function is the x*x*x or x^3

For integer value there is the first problem:

It scale to bignum very fast. Then there is a problem with the multiplication.

The maximum value is 1290 !

Code: Select all

set /A x=1291*1291*1291

result:

Code: Select all

-2143282125



How we can bypass this limit in dos batch?

Einstein1969

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Another javascript porting

#3 Post by Squashman » 19 Nov 2015 10:42

Judago, had created several native batch scripts for math to overcome the 32bit integer limitation. His old website is no longer active and I have not seen him on DosTips in a long time. I used his Division batch file. I will see if I ever downloaded his multiplication one.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Another javascript porting

#4 Post by Aacini » 19 Nov 2015 11:16

You may split a large number in groups of digits that can be managed in individual 32-bits operations; the number of digits in each group depends on the operations you want to perform on the large number. For example, to perform multiplications the groups can contain a maximum of 4 digits, because 99999*99999 exceed the maximum 32-bits number. You may review some examples of this method at these posts:

viewtopic.php?f=3&t=4022&p=22370#p22370
viewtopic.php?f=3&t=5270&p=31689#p31689
http://www.dostips.com/forum/viewtopic.php?f=3&t=3272&p=15878#p15878
http://stackoverflow.com/questions/20707290/how-to-find-large-factorials-using-a-batch-script/20715059#20715059

Antonio

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Another javascript porting

#5 Post by einstein1969 » 19 Nov 2015 11:27

Squashman wrote:Judago, had created several native batch scripts for math to overcome the 32bit integer limitation. His old website is no longer active and I have not seen him on DosTips in a long time. I used his Division batch file. I will see if I ever downloaded his multiplication one.


Thanks Squashman! I haved forgot this!

Here my backup if others needs.

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Another javascript porting

#6 Post by einstein1969 » 19 Nov 2015 15:34

I have seen the Judago work and I haven't understand the Judago algorithm.
It work very well on big number but is slow for my goal.

I'm considering the Aacini's links... Thanks

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Another javascript porting

#7 Post by Squashman » 19 Nov 2015 16:31

einstein1969 wrote:I have seen the Judago work and I haven't understand the Judago algorithm.
It work very well on big number but is slow for my goal.

I'm considering the Aacini's links... Thanks

Yes. Even Judago admits his script is slow but I think it does a great job handling floating point and large numbers.
viewtopic.php?p=20773#p20773

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Another javascript porting

#8 Post by einstein1969 » 20 Nov 2015 05:43

@Squashman
I agree. It's a great job.

@Aacini
I have seen the links you posted but i have not understand how to do a big moltiplication with these methods.

Can you help me with this "simple" operation?

Code: Select all

num=1234567*1234567


Einstein1969

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Another javascript porting

#9 Post by Aacini » 20 Nov 2015 16:08

einstein1969 wrote:@Aacini
I have seen the links you posted but i have not understand how to do a big moltiplication with these methods.

Can you help me with this "simple" operation?

Code: Select all

num=1234567*1234567


Einstein1969


The problem with this method is that it is neccessary to define in advance the maximum numbers it could manage in order to correctly manipulate both the numbers and the result. Of course, the "right way" to implement this method is to write a series of general-use subroutines that can perform the four basic arithmetic operations on two numbers of unlimited sizes; however, these programs are somewhat large and awkward, and I am a little bit lazy to write such non-interesting applications!

The example below is a particular case of this method that allows to multiply two numbers of up to 8 digits each:

Code: Select all

@echo off
setlocal

:nextNumbers
   set "numbers="
   set /P "numbers=Enter two numbers: "
   if not defined numbers goto :EOF
   call :Mul8x8 %numbers% product=
   echo The product is: %product%
   echo/
goto nextNumbers


This is the method used in this case;
each high:low part is a "quad" (four digits)

A = Ahigh : Alow
B = Bhigh : Blow

AxB  =                                      Ahigh : Alow
                                            x       Blow
                      ----------------------------------
                      carryLow  : Ahigh*Blow : Alow*Blow

     +
                                Ahigh : Alow
                                x      Bhigh
        ------------------------------------
        carryHigh : Ahigh*Bhigh : Alow*Bhigh


AxB  =                carryLow : Ahigh*Blow : Alow*Blow
     +  caryHigh : Ahigh*Bhigh : Alow*Bhigh


:Mul8x8 A B AxB=
setlocal EnableDelayedExpansion

rem Get sign and "quads" of first number
set /A "A=%1, Asign=A>>31|1, A*=Asign, Ahigh=A/10000, Alow=A%%10000"

rem Get sign and "quads" of second number
set /A "B=%2, Bsign=B>>31|1, B*=Bsign, Bhigh=B/10000, Blow=B%%10000"

rem Multiply A by low part of B
set /A term=        Alow*Blow,  AxBlow =term%%10000, carryLow=term/10000,   term=carryLow+Ahigh*Blow,  AxBhigh=term%%10000, carryLow=term/10000

rem Multiply A by high part of B, adding corresponding parts from previous product
set /A term=AxBhigh+Alow*Bhigh, AxBhigh=term%%10000, carryLow+=term/10000,  term=carryLow+Ahigh*Bhigh, carryLow=term%%10000, carryHigh=term/10000

rem Get the sign of the product
set /A AxBsign=Asign*Bsign
set "sign="
if %AxBsign% equ -1 set "sign=-"

rem Assemble the result
if %carryHigh% gtr 0 (
   set /A carryLow+=10000, AxBhigh+=10000, AxBlow+=10000
   set "AxB=%carryHigh%!carryLow:~1!!AxBhigh:~1!!AxBlow:~1!"
) else if %carryLow% gtr 0 (
   set /A AxBhigh+=10000, AxBlow+=10000
   set "AxB=%carryLow%!AxBhigh:~1!!AxBlow:~1!"
) else if %AxBhigh% gtr 0 (
   set /A AxBlow+=10000
   set "AxB=%AxBhigh%!AxBlow:~1!"
) else (
   set "AxB=%AxBlow%"
)
endlocal & set "%3=%sign%%AxB%"
exit /B

As you can see, the method is a real nuisance... All this stuff can be written in a better way using arrays that allows to manage unlimited digits in each number, but in this case it is convenient to include a decimal point in order to perform fixed point arithmetic. However, in this case the method is more complicated because the decimal point position. Perhaps some day, when I have too much time to spare and I be really bored...

Output example:

Code: Select all

Enter two numbers: -3 4
The product is: -12

Enter two numbers: 1234567 1234567
The product is: 1524155677489

Enter two numbers: 12345678 87654321
The product is: 1082152022374638

Enter two numbers: 99999999 99999999
The product is: 9999999800000001

Antonio

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Another javascript porting

#10 Post by einstein1969 » 25 Nov 2015 04:32

Thanks Antonio!

This show me how to manage a multiply with about doubling the precision.

The next step is more difficult.

For more semplicity I partial ported the code:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

  rem setting batch canvas like. X*Y = 40*40 = 0..39*1..40
  set /A width=40, height=40

  rem Adjust for pretty results
  set /a w=width+2, h=height+2
  mode %w%,%h%
  set w=&set h=

  rem amount=number of particle, milliseconds=millisecond update
  set /A amount=8, milliseconds=100

  rem Sqrt macro
  set "Sqrt(N)=( M=(N), x=M/(11*1024)+40, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"

  rem prepare screenbuffer
  For /L %%l in (1,1,%width%) do set "_empty=!_empty! "
  set "g=.@"

  set /A factor = 9, min_proximity = 4*10000

  rem create particle
  for /L %%I in (1,1,%amount%) do call :particle %%I

  for /L %%? in () do (

    rem call :fading
    call :acceleration_accumulation
    rem delay
    rem C:\windows\system32\pathping 127.0.0.1 -n -q 1 -p %milliseconds% >nul

    rem Draw screenbuffer /canvas
    cls & For /L %%l in (1,1,%height%) do echo( !L%%l!
    For /L %%l in (1,1,%height%) do set L%%l=
     
  )

exit /b

:acceleration_accumulation

  for /L %%I in (1,1,%amount%) do (
    rem title %%I
    set /A Js=%%I+1

    for /L %%J in (!Js!,1,%amount%) do (

       set /A vec.x=p[%%I].pos.x-p[%%J].pos.x, vec.y=p[%%I].pos.y-p[%%J].pos.y

       rem check for big number
       if !vec.x! gtr 46340 (set /a "X2=vec.x/10*(vec.x/10)/100") else set /a X2=vec.x*vec.x/10000
       if !vec.y! gtr 46340 (set /a "Y2=vec.y/10*(vec.y/10)/100") else set /a Y2=vec.y*vec.y/10000

       set /A Len=X2+Y2
       if !Len! gtr 0 set /A "Len=%Sqrt(N):N=Len%"

       rem correct for sqrt fixed point. Not correct for Len^3 overflow
       rem set /A Len*=100

       rem now Len is multiply for 100 and not 10000
       rem echo !len! prima %%I %%J !vec.x! !vec.y! !X2! !Y2!
       set /A Len=Len*Len/100*Len/factor
       rem echo !len! dopo
       if !Len! equ 0 set Len=1
       
       rem echo %%I %%J !x! !y! !p[%%I].pos.x! !p[%%J].pos.x! !p[%%I].pos.y! !p[%%J].pos.y!
       rem pause

       set /A "vec.x/=Len,  y/=Len"

       Rem this not work!
       rem if !Len! gtr !min_proximity! set /A p[%%J].acc.x+=vec.x, p[%%J].acc.y+=vec.y, p[%%I].acc.x-=vec.x, p[%%I].acc.y-=vec.y
    )

rem ###############################################################
    rem Particle.step
    rem validate acceleration . SI PUO' TOGLIERE?
    rem if not defined x1 (x1=0,y1=0) OR if not defined y1 (x1=0,y1=0)
    if not defined p[%%I].acc.x set /A p[%%I].acc.x=0, p[%%I].acc.y=0
    if not defined p[%%I].acc.y set /A p[%%I].acc.x=0, p[%%I].acc.y=0

    rem echo vel.x:!p[%%I].vel.x! vel.y:!p[%%I].vel.y!

    set /A p[%%I].vel.x+=p[%%I].acc.x, p[%%I].vel.y+=p[%%I].acc.y

    rem lenght: (x*x+y*y)^(1/2)
    set /A speed=p[%%I].vel.x*p[%%I].vel.x/10000+p[%%I].vel.y*p[%%I].vel.y/10000
    if !speed! gtr 0 set /A "speed=%Sqrt(N):N=speed%"
    if !speed! gtr !speed_limit! set /A p[%%I].vel.x/=speed*10000/speed_limit, p[%%I].vel.y=speed*10000/speed_limit

    rem echo !p[%%I].pos.x!+!p[%%I].vel.x! !p[%%I].pos.y!+!p[%%I].vel.y!
    rem pause

    set /A p[%%I].pos.x+=p[%%I].vel.x, p[%%I].pos.y+=p[%%I].vel.y

    set /A p[%%I].acc.x=0, p[%%I].acc.y=0

    rem X*Y = 40*40 = 0..39*1..40
    if !p[%%I].pos.x! lss 0 set /A p[%%I].pos.x=0, p[%%I].vel.x=p[%%I].vel.x*-bounce_damping/10000
    if !p[%%I].pos.y! lss 10000 set /A p[%%I].pos.y=10000, p[%%I].vel.y=p[%%I].vel.y*-bounce_damping/10000

    set /A cw=%width%*10000-10000, ch=%height%*10000
    if !p[%%I].pos.x! gtr !cw! set /A p[%%I].pos.x=cw, p[%%I].vel.x=p[%%I].vel.x*-bounce_damping/10000
    if !p[%%I].pos.y! gtr !ch! set /A p[%%I].pos.y=ch, p[%%I].vel.y=p[%%I].vel.y*-bounce_damping/10000
rem ###############################################################
    rem draw particle
    set /A x=p[%%I].pos.x/10000, y=p[%%I].pos.y/10000
    rem PLOTTING
    if !y! lss 1 pause
    if not defined L!y! set "L!y!=%_empty%"
    For /F "tokens=1-3" %%x in ("!x! !y! 1") do (
      set "L=!L%%y:~%%x!"
      set "L%%y=!L%%y:~0,%%x!!g:~%%z,1!!L:~1!"
    )
rem ###############################################################
  )
exit /b

:particle
:: %1 particle index
rem particle initializing, fixedpoint

  rem var initial_speed = 1 , var speed_limit = 4, bounce_damping = 0.5 =>10/2*1000
  rem multiply by 2
  set /A initial_speed = 2*10000, speed_limit = 8*10000, bounce_damping = 10/2*2*1000
  set /A p[%1].acc.x=0, p[%1].acc.y=0
  set /A p[%1].vel.x=!random!*10000/32767 * initial_speed/10000 - initial_speed * 10/2*1000 /10000
  set /A p[%1].vel.y=!random!*10000/32767 * initial_speed/10000 - initial_speed * 10/2*1000 /10000
 
  set /A p[%1].pos.x=!random!*10000/32768*width, p[%1].pos.y=!random!*10000/32768*height+10000 & rem X*Y = 40*40 = 0..39*1..40

  rem set /A val=!random!*10000/32767 * initial_speed/10000
  rem echo vel.x:!p[%1].vel.x! vel.y:!p[%1].vel.y! !val!
  rem pause
exit /b



The question is the CUBE function with the next Division by "factor"

I think that its necessary to do a CUBE_DIV piece.

The problem is: store the result of CUBE and then DIVIDE or make a progressive multiple and divide how the showed code ?

Einstein1969

Post Reply