Another javascript porting
Moderator: DosItHelp
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Another javascript porting
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.
EDIT:
main article
Einstein1969
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.
EDIT:
main article
Einstein1969
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Another javascript porting
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 !
result:
How we can bypass this limit in dos batch?
Einstein1969
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
Re: Another javascript porting
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.
Re: Another javascript porting
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
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
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Another javascript porting
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.
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Another javascript porting
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
It work very well on big number but is slow for my goal.
I'm considering the Aacini's links... Thanks
Re: Another javascript porting
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
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Another javascript porting
@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?
Einstein1969
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
Re: Another javascript porting
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
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Another javascript porting
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:
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
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