Πέμπτη 12 Μαρτίου 2026

Integer Square Root (Addition: BigInteger)

Update: https://rosettacode.org/wiki/Isqrt_(integer_square_root)_of_X#M2000_Interpreter


Check function IntSqrt using BigInteger at the the last part of module integer_square_root

module integer_square_root (f=-2) {
Locale 1033
function comma$(a) {
string z, f, p
const c$=locale$(15)
if type$(a)="BigInteger" then z=str$(a) else z=a
long m=len(z)
z=strrev$(z)
for i=1 to len(z) step 3
p=mid$(z,i, 3)
f+=p+if$(m-i>=3->c$,"")
next
=strrev$(f)
}
function IntSqrt(x as long long) {
long long q=1, z=x, t, r
do q*=4&& : until (q>x)
while q>1&&
q|div 4&&:t=z-r-q:r|div 2&&
if t>-1&& then z=t:r+= q
end while
=r
}
long i
print #f, "The integer square root of integers from 0 to 65 are:"
for i=0 to 65
print #f, IntSqrt(i)+" ";
next
print #f
print #f, "Using Long Long Type"
print #f, "The integer square roots of powers of 7 from 7^1 up to 7^21 are:"
for i=1 to 21 step 2 {
print #f, "IntSqrt(7^"+i+")="+comma$(IntSqrt(7&&^i))+" of 7^"+i+" ("+comma$(7&&^I)+")"
}
print #f
function IntSqrt(x as decimal) {
decimal q=1, z=x, t, r
do q*=4 : until (q>x)
while q>1
q/=4:t=z-r-q:r/=2
if t>-1 then z=t:r+= q
end while
=r
}
print #f, "Using Decimal Type"
print #f, "The integer square roots of powers of 7 from 7^23 up to 7^33 are:"
decimal j,p
for i=23 to 33 step 2 {
p=1:for j=1 to i:p*=7@:next
print #f, "IntSqrt(7^"+i+")="+comma$(IntSqrt(p))+" of 7^"+i+" ("+comma$(p)+")"
}
print #f


function IntSqrt(x as double) {
double q=1, z=x, t, r
do q*=4 : until (q>x)
while q>1
q/=4:t=z-r-q:r/=2
if t>-1 then z=t:r+= q
end while
=r
}
print #f, "Using Double Type"
print #f, "The integer square roots of powers of 7 from 7^19 up to 7^35 are:"
for i=19 to 35 step 2 {
print #f, "IntSqrt(7^"+i+")="+comma$(IntSqrt(7^i))+" of 7^"+i+" ("+(7^i)+")"
}
print #f
print #f, "Using BigInteger Type"

function IntSqrt(x as BigInteger) {
BigInteger q=1, z=x, t, r
do q*=4 : until (q>x)
while q>1
q|div 4:t=z-r-q:r|div 2
if t>-1 then z=t:r+= q
end while
=r
}
BigInteger Z=7
z=modpow(7u, 19u, BigInteger("1"+String$("0", 100)))
print #f, "The integer square roots of powers of 7 from 7^19 up to 7^35 are:"
for i=19 to 73 step 2 {
print #f, "IntSqrt(7^"+i+")="+comma$(IntSqrt(Z))+" of 7^"+i+" ("+comma$(Z)+")"
Z*=7*7
}
print #f

}
open "" for output as #f // f = -2 now, direct output to screen
integer_square_root
close #f
open "out.txt" for output as #f
integer_square_root f
close #f
win "notepad", dir$+"out.txt"


Output:

The integer square root of integers from 0 to 65 are:

0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 

Using Long Long Type

The integer square roots of powers of 7 from 7^1 up to 7^21 are:

IntSqrt(7^1)=2 of 7^1 (7)

IntSqrt(7^3)=18 of 7^3 (343)

IntSqrt(7^5)=129 of 7^5 (16,807)

IntSqrt(7^7)=907 of 7^7 (823,543)

IntSqrt(7^9)=6,352 of 7^9 (40,353,607)

IntSqrt(7^11)=44,467 of 7^11 (1,977,326,743)

IntSqrt(7^13)=311,269 of 7^13 (96,889,010,407)

IntSqrt(7^15)=2,178,889 of 7^15 (4,747,561,509,943)

IntSqrt(7^17)=15,252,229 of 7^17 (232,630,513,987,207)

IntSqrt(7^19)=106,765,608 of 7^19 (11,398,895,185,373,143)

IntSqrt(7^21)=747,359,260 of 7^21 (558,545,864,083,284,007)


Using Decimal Type

The integer square roots of powers of 7 from 7^23 up to 7^33 are:

IntSqrt(7^23)=5,231,514,822 of 7^23 (27,368,747,340,080,916,343)

IntSqrt(7^25)=36,620,603,758 of 7^25 (1,341,068,619,663,964,900,807)

IntSqrt(7^27)=256,344,226,312 of 7^27 (65,712,362,363,534,280,139,543)

IntSqrt(7^29)=1,794,409,584,184 of 7^29 (3,219,905,755,813,179,726,837,607)

IntSqrt(7^31)=12,560,867,089,291 of 7^31 (157,775,382,034,845,806,615,042,743)

IntSqrt(7^33)=87,926,069,625,040 of 7^33 (7,730,993,719,707,444,524,137,094,407)


Using Double Type

The integer square roots of powers of 7 from 7^19 up to 7^35 are:

IntSqrt(7^19)=106,765,608 of 7^19 (1.13988951853731E+16)

IntSqrt(7^21)=747,359,260 of 7^21 (5.58545864083284E+17)

IntSqrt(7^23)=5,231,514,822 of 7^23 (2.73687473400809E+19)

IntSqrt(7^25)=36,620,603,758 of 7^25 (1.34106861966396E+21)

IntSqrt(7^27)=256,344,226,312 of 7^27 (6.57123623635343E+22)

IntSqrt(7^29)=1,794,409,584,184 of 7^29 (3.21990575581318E+24)

IntSqrt(7^31)=12,560,867,089,291 of 7^31 (1.57775382034846E+26)

IntSqrt(7^33)=87,926,069,625,040 of 7^33 (7.73099371970744E+27)

IntSqrt(7^35)=615,482,487,375,282 of 7^35 (3.78818692265665E+29)


Using BigInteger Type

The integer square roots of powers of 7 from 7^19 up to 7^35 are:

IntSqrt(7^19)=106,765,608 of 7^19 (11,398,895,185,373,143)

IntSqrt(7^21)=747,359,260 of 7^21 (558,545,864,083,284,007)

IntSqrt(7^23)=5,231,514,822 of 7^23 (27,368,747,340,080,916,343)

IntSqrt(7^25)=36,620,603,758 of 7^25 (1,341,068,619,663,964,900,807)

IntSqrt(7^27)=256,344,226,312 of 7^27 (65,712,362,363,534,280,139,543)

IntSqrt(7^29)=1,794,409,584,184 of 7^29 (3,219,905,755,813,179,726,837,607)

IntSqrt(7^31)=12,560,867,089,291 of 7^31 (157,775,382,034,845,806,615,042,743)

IntSqrt(7^33)=87,926,069,625,040 of 7^33 (7,730,993,719,707,444,524,137,094,407)

IntSqrt(7^35)=615,482,487,375,282 of 7^35 (378,818,692,265,664,781,682,717,625,943)

IntSqrt(7^37)=4,308,377,411,626,977 of 7^37 (18,562,115,921,017,574,302,453,163,671,207)

IntSqrt(7^39)=30,158,641,881,388,842 of 7^39 (909,543,680,129,861,140,820,205,019,889,143)

IntSqrt(7^41)=211,110,493,169,721,897 of 7^41 (44,567,640,326,363,195,900,190,045,974,568,007)

IntSqrt(7^43)=1,477,773,452,188,053,281 of 7^43 (2,183,814,375,991,796,599,109,312,252,753,832,343)

IntSqrt(7^45)=10,344,414,165,316,372,973 of 7^45 (107,006,904,423,598,033,356,356,300,384,937,784,807)

IntSqrt(7^47)=72,410,899,157,214,610,812 of 7^47 (5,243,338,316,756,303,634,461,458,718,861,951,455,543)

IntSqrt(7^49)=506,876,294,100,502,275,687 of 7^49 (256,923,577,521,058,878,088,611,477,224,235,621,321,607)

IntSqrt(7^51)=3,548,134,058,703,515,929,815 of 7^51 (12,589,255,298,531,885,026,341,962,383,987,545,444,758,743)

IntSqrt(7^53)=24,836,938,410,924,611,508,707 of 7^53 (616,873,509,628,062,366,290,756,156,815,389,726,793,178,407)

IntSqrt(7^55)=173,858,568,876,472,280,560,953 of 7^55 (30,226,801,971,775,055,948,247,051,683,954,096,612,865,741,943)

IntSqrt(7^57)=1,217,009,982,135,305,963,926,677 of 7^57 (1,481,113,296,616,977,741,464,105,532,513,750,734,030,421,355,207)

IntSqrt(7^59)=8,519,069,874,947,141,747,486,745 of 7^59 (72,574,551,534,231,909,331,741,171,093,173,785,967,490,646,405,143)

IntSqrt(7^61)=59,633,489,124,629,992,232,407,216 of 7^61 (3,556,153,025,177,363,557,255,317,383,565,515,512,407,041,673,852,007)

IntSqrt(7^63)=417,434,423,872,409,945,626,850,517 of 7^63 (174,251,498,233,690,814,305,510,551,794,710,260,107,945,042,018,748,343)

IntSqrt(7^65)=2,922,040,967,106,869,619,387,953,625 of 7^65 (8,538,323,413,450,849,900,970,017,037,940,802,745,289,307,058,918,668,807)

IntSqrt(7^67)=20,454,286,769,748,087,335,715,675,381 of 7^67 (418,377,847,259,091,645,147,530,834,859,099,334,519,176,045,887,014,771,543)

IntSqrt(7^69)=143,180,007,388,236,611,350,009,727,669 of 7^69 (20,500,514,515,695,490,612,229,010,908,095,867,391,439,626,248,463,723,805,607)

IntSqrt(7^71)=1,002,260,051,717,656,279,450,068,093,686 of 7^71 (1,004,525,211,269,079,039,999,221,534,496,697,502,180,541,686,174,722,466,474,743)

IntSqrt(7^73)=7,015,820,362,023,593,956,150,476,655,802 of 7^73 (49,221,735,352,184,872,959,961,855,190,338,177,606,846,542,622,561,400,857,262,407)


Cube 3D


From an old program here: https://rosettacode.org/wiki/Draw_a_rotating_cube#M2000_Interpreter

Adding a second rotation (transform cartesian to polar coordinates) and hidden line removal using a simple algorithm. It is not a free rotation cube program although. A simple rotation plus a rotation in Z axis. 

Module Cube3D {
form 80, 32
smooth on // enable GDI+ smooth lines
pi=3.1415926
single zoff=0.577350
single cylr=1.632993
oX=scale.x div 2 : oY=scale.y div 2
SCALE=min.data(oX, oY)/2*.6
gradient 0, 5
single theta = 0, dtheta = 0.015, dt = 1000/60, phi = 0
single ScZof=SCALE/zoff
single ScZofM=SCALE*zoff
dim cylphi(6) as single, x() as single
cylphi(0)=pi/6, 5*pi/6, 3*pi/2, 11*pi/6, pi/2, 7*pi/6
every DT {
if mouse then
(oX, oY)=(mouse.x,mouse.y)
if dtheta<2.8 then dtheta*=1.05
else
dtheta = 0.15
end if
theta=theta mod (2*pi)
aa=theta div (pi/32)
rem pen 15 {print @(5,5),aa}
dim x(6)=oX : for i=0 to 5: x(i) += SCALE*cylr*rcos(cylphi(i)+theta):next
width 4{drawcube()}: refresh 100 : IF keypress(32) then exit
theta += pi/32*dtheta
phi+=.015
gradient 0, 5: cursor 0,0
Print "Press space to exit",,"Press A for wire frame",,"Press any mouse button to move cube",,Time$(Now)
}
sub drawcube()
local boolean skip, skip2, wire
local complex mm
if keypress(65) then wire=true : local aa=5000
' move oX,oY
' circle 300
for i= 0 to 2
skip2=0
skip=0
if aa>=16 and aa<=27 and i=1 then
skip=1
skip2=1
else.if aa>=58 or aa<=5 and i=2 then
skip=1
skip2=1
else.if aa>=37 and aa<=48 and i=0 then
skip=1
skip2=1
end if
if wire then skip=false:skip2=false
if skip else
      mm=(x(i)-oX, ScZofM i)
move oX, oY
step angle arg(mm)+phi, mod(mm)
mm=(0, -ScZof i)+mm
draw angle arg(mm)+phi, -mod(mm), 15 ' 11
end if
if aa>=5 and aa<=15 and i=0 then
else.if aa>=27 and aa<=37 and i=1 then
skip=1
else.if aa>=48 and aa<=58 and i=2 then
skip2=1
else
if aa>=27 and aa<=37 and i=0 then
skip2=1
else.if aa>=48 and aa<=58 and i=0 then
skip=1
else.if aa>=5 and aa<=15 then
if i=2 then skip=1 else skip2=1
end if
mm=(0, -ScZof i)
move oX, oY
step angle arg(mm)+phi, mod(mm)
mm=(x(5-i)-oX, ScZofM i)+mm
draw angle -arg(mm)+phi, mod(mm), 15' 14
end if
if skip2 else
mm=(x(i)-oX, -ScZofM i)
move oX, oY
step angle -arg(mm)+phi, mod(mm)
mm=(x((i+1) mod 3 + 3)-oX, ScZofM i)-mm
draw angle -arg(mm)+phi, mod(mm), 15' 13
end if
      if skip else
      'move x(i),oY-ScZofM
mm=(x(i)-oX, -ScZofM i)
move oX, oY
step angle -arg(mm)+phi, mod(mm)
mm=(x(i mod 3 + 3)-oX, ScZofM i)-mm
draw angle -arg(mm)+phi, mod(mm), 15
end if
next
end sub
}
Cube3D


 

Τετάρτη 11 Μαρτίου 2026

A SetTimeout functionality for M2000

This program  run two loops for i from 0 to 7 (last value after loop is 8). For each body of loop we make a call for a function using the i value, after 1 second. The first loop has a lambda function which can hold i as a closure with the "then" value. In the second loop we make a lazy evaluation block, where the body of the function is exactly a part of the module (we can see variables, like i, and anything we make there including subs but not for this example)

Although a normal function has own name space, there are other functions:

1) A lambda function has two parts, the list of closures (can be empty) and the function body same as the body of a normal function. The closures are like local to body. We can use lambda() to call recursive and the closures are the same for each call (so the closures are local but for all calls in a recursive manner). Each call in the series of call may or may not have the same stack of values. If we use Call statement we pass the same stack of values (with the passing parameters at the top, from we read first values). If we use the function in an expression then a new stack of values attached to function (so we can use this for any number of parameters, so the parameters which not used deleted). This functionality for stack of values are the same as for the normal function.

2) A simple function. This function has format like Sub, using Function name()  and in an another line the End Function. We call @name() and the name has not to be same as the internal functions. This type cannot passed by reference and cannot used with Call statement. This type use the same stack of values from the caller. This type also has to use Local to create local variables, because luck a namespace (it use the callers namespace). This function can be called from the module/function which exist - always at the bottom side of the code, the same side we put the Subs. Also this function can be called from a module/function which we define as child module/function and there is no a function with the same name at these children (so we can reuse a function from multiple child modules/funcitons.

3)A "dummy" function, is a body of function which run as a module with or without same stack of values. The function isn't dummy if we use it like all functions. But here we use the Lazy$() which make a special reference bounding a reference to the specific namespace (same as the one where the Lazy$() executed). We can use Lazy$() using a formula like Lazy$(x+y). The example below show a a way to use a Group as a value used as a call back (we call the Inner module and from the Inner we call back before the Inner module end execution and return, and here we call the Value part of Group Counter which alter the Counter.count variable)  

Module TestLazy {
Group Counter {
count=0
Value {
=.count
.count++
}
}
x=10
y=3
Module Inner(&a()) {
Print a()
Print a()
}
Inner lazy$(x+y+Counter) ' return 13 then 14
Inner lazy$(x+y+Counter) ' return 15 then 16
Print Counter.count=4 ' true
}
TestLazy


This is the example for "dummy" function (this is a way to have a call back, which mean we call the Inner module and from the Inner we call back before the Inner module end execution and return)

Module TestDummyFunction {
flush
i=100
function aa(x) {
=x+i
}
Module Inner(&a()) {
Print a(10)+Stack.size

}
Function Inner2(&a()) {
Print a(10)+Stack.size
=0
}
Push 1,2,3
Inner Lazy$(&aa()) ' 113 (110 + 3)
M=Inner2(Lazy$(&aa())) ' 110 (110 + 0)
Print Number, Number, Number ' pop 3,2,1
' not valid because now we call it like a normal function
Print Valid(aa(10))=0 ' true
Try ok {
Call aa(10)
}
' Unkown Variable I Missing Number Exrpession
Print "Finish:"+If$(ok or Error -> Error$, "ok")
}
TestDummyFunction


About Threads


The main example, has two different setTimeout, one for lambda function and another one for a reference of function (we can pass the Lazy$() value which always a reference of function.

When we use the first one, we pass a copy of lambda in the Thread Stack of values (each thread has a body at the same namespace as the one which made it, le say the parent, a stack of values different from the parent, and maybe has a list of static values (always with different name from local variables). The body of thread executed in each interval. By default we use Thread.Plan Sequential  (not executed here, because by default it this plan - not the concurrent plan). We can terminate a thread through the thread using the Thread This Erase statement. Each thread has a number so the N variable hold the number, but here we don't need this number, we can erase the thread after the first run. Also we place a value on threads stack. This can be done using the Thread N Execute using statements to execute for threads stack of values. (also we can make Static variables here. but these cannot have names of local variables like i).

Anything we make in a Thread may or may not be used next time. If we exclude the For this { } block (used for temporary definitions) we can also exclude the New in Read statement (normally a reference can't be assigned second time, but this not apply to functions references) but we get different output, because the Print a() (last statement to execute) find the last a() body which get from reference. So using New for Read (Read New) we make always new definitions which shadow old definitions. So we use the temporary block (For this { }  block) to delete the new definition when we do not use it. So now the last statement print 1234 (the function a() preserved)


The examples for Javascript are from https://gist.github.com/mirajehossain/js.md


Thread.Plan Sequential  ' this is by default
Module TestSetTimeOut {
' Normaly a function has own namespace
i=100
function a() {
=1234
}
function checkit() {
i=555
Print i
}
Call checkit()
Print i=100 ' true
Rem { // Javascript
        for (let i = 0; i < 7; ++i) {
          setTimeout(function () {
            console.log(i);
            // => 0
            // => 1
            // => 2
            // => 3
            // => 4
            // => 5
            // => 6
            // => 7
          }, 1000);
        }
}

' like Let in Javascript we place current i to F, so we get after the loop all values again.
for i=0 to 7
print "value:";i : Refresh
F=lambda i -> {
Print i:Refresh
}
SetTimeOut(F, 1000)
' SetTimeOut((lambda i -> {Print i, "OK":Refresh}), 1000)
next i
WaitThreads()
Rem { // Javascript
        for (var i = 0; i < 7; ++i) {
          setTimeout(function () {
            console.log(i);
            // => 8
            // => 8
            // => 8
            // => 8
            // => 8
            // => 8
            // => 8
            // => 8
          }, 1000);
        }
}
' like Var we get the last value of i (which is 8) for all calls through threads
' becaue we pass the same i as the one which exist.
for i=0 to 7
print "value:";i : Refresh
function enviroment {
Print i:Refresh
}
function enviroment2 {
Print i, "OK":Refresh
}
SetTimeOutVar(Lazy$(&enviroment()), 1000)
' SetTimeOutVar(Lazy$(&enviroment2()), 1000)
next i
WaitThreads()
' Bonus stage
' We can pass by reference the lambda function, as function reference.
' But we get always the same reference, so we get the last F with i=7
for i=0 to 7
print "value:";i : Refresh
F=lambda i -> {
Print i:Refresh
}
SetTimeOutVar(&F(), 1000)
next i
WaitThreads()
Print a()
Sub SetTimeOut(f as lambda, msec)
Local N
thread {
for this { ' we erase the function after exit this block
Read New a
Call a()
}
Thread this Erase
} as N
Thread N Execute Push f
Thread N interval msec
End Sub
Sub SetTimeOutVar(f$, msec)
Local N
thread {
For This { ' we erase the function after exit this block
Read New &a()
Call a()
}
Thread this Erase
} as N
Thread N Execute Push f$
Thread N interval msec
End Sub
Sub WaitThreads()
main.task 10 {}
End Sub
}
TestSetTimeOut

Fast Fourier transform using complex type

 

There is a post here (which updated by me) : https://rosettacode.org/wiki/Fast_Fourier_transform#M2000_Interpreter

M2000 use Complex type native. Look at Sub FFT we can use as *Complex[] to restrict the parameter to be a pointer to a RefArray type of Complex type. Because we pass a pointer by value, the RefArray values are like passed by reference, because we alter values. We need this because in other recursive calls we exchange the pointers (out in place of buf and puf in place of out).

module FFT {
' print $("0.000", 16)   ' #1 (use #1, #2, #3 for 4 decimals for printing numbers )
locale 1033
open "output.txt" for wide output as #F
complex buf[7], out[7]
buf[0]|r = 1: buf[1]|r = 1: buf[2]|r = 1: buf[3] = (1, 0i)
showArr(buf, "Input")
FFT(out, buf, 0, 1, 8)
ShowArr(out, "Output")
' print $("") ' #2
close #F
print #-2, eval$(buffer(dir$+"output.txt"))
Sub ShowArr(m, mes as string)
local n, mx=len(m)
print #F, mes;": (real imag abs)"
while n<mx
' print m[n]  ' #3
' round(number) round to 13th decimal, is same as round(exp, 13)
' modulus of complex number: Mod(complex)
print #F, format$("{0:0:-10} {1:-10} {2:-12}",m[n]|r, round(m[n]|i, 4)+"", round(mod(m[n]), 8)+"")
n++
end while
End Sub
Sub FFT()
Shift 5
Read New N as long
FFT1()
End Sub
' FFT1() use N always
Sub FFT1(buf as *Complex[], out as *Complex[], begin as Long, stp as Long)
If stp < N Then
FFT1(out, buf, begin, 2 * stp)
FFT1(out, buf, begin + stp, 2 * stp)
Local i as long, t as complex
for i=0 to N-1 step 2*stp
t = Polar(1, -pi* i / N) * out[begin + i + stp]
buf[begin + i div 2] = out[begin + i] + t
buf[begin + (i + N) div 2] = out[begin + i] - t
next
End If
End Sub
}
FFT

Output.txt

Input: (real imag abs) 1 0 1 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 Output: (real imag abs) 4 0 4 1 -2.4142 2.61312593 0 0 0 1 -0.4142 1.0823922 0 0 0 1 0.4142 1.0823922 0 0 0 1 2.4142 2.61312593