Dr. Jim's QL Dumping Ground

Anything QL Software or Programming Related.
EmmBee
Trump Card
Posts: 240
Joined: Fri Jan 13, 2012 5:29 pm
Location: Kent

Re: Dr. Jim's QL Dumping Ground

Post by EmmBee »

TMD2003 wrote:Hails!
Anyway, here's the listing. You know what to do with it.
Hails!

Trying the program with 999983 took 34 seconds. This was using QPC2 v4.05. I was rather surprised at such a slow timing, especially since I have recently upgraded my PC to use a solid-state drive.

Looking through the code, I see line 290 FOR n=1 TO f1/2 STEP 2. As I see it, there should be no need to go further than the square root of f1. I tried this out but found that it misses the final f1 value as the final factor. So, I added f1 to the FOR loop. QL SuperBASIC does allow this. Also included are the changes suggested by Tofro and Steve. Here is the updated code …

Code: Select all

100 CLS
110 initial_input
120 factor_array(f0)
130 factors_found
140 STOP
150 REMark ==========================
160 DEFine PROCedure initial_input
170 REMark ==========================
180 PRINT "INPUT INTEGER TO FACTORISE"\"(min.2, max.999999)"\\"-> ";
190 REPeat loop1
200   INPUT f0
210   IF f0>=2 AND f0<=999999 AND f0=INT(f0) THEN EXIT loop1
220 END REPeat loop1
230 END DEFine initial_input
240 REMark ==========================
250 DEFine PROCedure factor_array(f1)
260 REMark ==========================
270 LOCal n,cf
280 DIM f(19): f1=f0
290 FOR n=1 TO SQRT(f1) STEP 2, f1
300 cf=n: IF n=1 THEN cf=2
310 AT 5,0: PRINT "Dividing by ";cf
320 REPeat loop2
330   IF cf*((f1/cf)-INT(f1/cf))<>0 THEN EXIT loop2
340   f1=f1/cf: f(f(0)+1)=cf: f(0)=f(0)+1
350   IF f1=1 THEN RETurn
360 END REPeat loop2
370 END FOR n
380 IF f1=f0 THEN f(0)=1: f(1)=f1
390 END DEFine factor_array
400 REMark ==========================
410 DEFine PROCedure factors_found
420 REMark ==========================
430 LOCal n
440 AT 5,0: PRINT "NUMBER OF FACTORS = ";f(0)\\"FACTORS:"
450 FOR n=1 TO f(0)-1: PRINT f(n)!"x ";: END FOR n: PRINT f(f(0));
460 IF f(0)=1 THEN PRINT "is a PRIME NUMBER"
470 END DEFine factors_found
This does seem to work. Running this new version with 999983, the result was instant!

By the way, I can recommend using a solid-state drive. My PC now boots up much quicker, and the long delays I have encountered in the past no longer occur.

EmmBee


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by pjw »

I found the FOR loop syntax new to me. I would have expected:

Code: Select all

FOR i = 1 to 5, 8 STEP 2
to be the right way to do it (It isnt!) Not

Code: Select all

FOR i = 1 to 5 STEP 2, 8
So Ive learnt two new things about FOR loops quite recently, summed up here:

Code: Select all

FOR i = 1 to 5 STEP 2, 8:		REMark Note the REMark! (SMSQ/E only!)
	PRINT i
END FOR i


Per
dont be happy. worry
- ?
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by pjw »

The other thing, I dont see why the limit is set to 999999. It could go up to 2^31-1, no?
I fiddled the limit and tried 999999999 (nine nines) on Qemulator with Qdos JS at Gold Card speed. It took 106 seconds to factorise. If you rem out line 310 in your code, you can halve the time. I didnt have the patience to do more than a few simple tests at QL speed.
I have an ancient routine from my benighted past that does the same job in about a 1/4 the time, but it is so ugly I wouldnt dare to post it here ;)


Per
dont be happy. worry
- ?
stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Dr. Jim's QL Dumping Ground

Post by stevepoole »

Yes Per,

You are right, the routine is ok with big numbers.

With f0='9999999999999999999', the program factorises correctly on QPC in 53 seconds, but f() needs to be DIMed as 39 !

with f0='1234567890123456789', the answer is right in less than a second...

And the limit is for yet bigger strings.... but then most of the factors are '2's.

Steve.


stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Dr. Jim's QL Dumping Ground

Post by stevepoole »

Hi Again,

After further tests,the limit is 'f0='999999999', as with 10 digits there are rounding errors....

Ie: a='1234567891': b='1234567892': print a=b gives true !

Steve.
____________


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by pjw »

stevepoole wrote:<>After further tests,the limit is 'f0='999999999', as with 10 digits there are rounding errors....
Yes, the positive limit for precision on Qdos/SMSQ is 2^31-1, which = 2,147,483,647 - a 10-digit number. You can see why: Heres the floating point representation of that number in hex (mantissa:exponent) $081F:7FFFFFFF.


Per
dont be happy. worry
- ?
Derek_Stewart
Font of All Knowledge
Posts: 3928
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Dr. Jim's QL Dumping Ground

Post by Derek_Stewart »

pjw wrote:I found the FOR loop syntax new to me. I would have expected:

Code: Select all

FOR i = 1 to 5, 8 STEP 2
to be the right way to do it (It isnt!) Not

Code: Select all

FOR i = 1 to 5 STEP 2, 8
So Ive learnt two new things about FOR loops quite recently, summed up here:

Code: Select all

FOR i = 1 to 5 STEP 2, 8:		REMark Note the REMark! (SMSQ/E only!)
	PRINT i
END FOR i
Hi Per,

I did not know about the extra syntax in the FOR statement.

I had a look at the Superbasic online manual, for more information the syntax. But the description is a little lacking.

Is there any other documentation?


Regards,

Derek
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by pjw »

Hi Derek,
Actually The SuperBASIC Manual does a good job of describing the syntax by example. The SuperBASIC Manual wasnt available when I started learning, and was too expensive by the time I felt I knew sufficient, so I dont have the habit of referring to it. But almost everything is in there. Howzabout:

Code: Select all

 FOR x=2,4 TO 10 STEP 2,4.5,7 TO -4 STEP -.2: PRINT x,
I didnt find the bit about

Code: Select all

FOR i = 1 to 5 STEP 2, 8:      REMark Note the REMark! (SMSQ/E only!)
..
END FOR i
but there was other (for me) new stuff. Its the right place to go for beginners! and nice for the odd browse on a lazy afternoon for old timers and alleged knowitalls.
Otherwise JJ's The Definitive Handbook may be the place to look. After all the syntax graphs actually used in the original SuperBASIC are listed there, although they dont entirely apply to MBASIC and SBASIC.


Per
dont be happy. worry
- ?
Derek_Stewart
Font of All Knowledge
Posts: 3928
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Dr. Jim's QL Dumping Ground

Post by Derek_Stewart »

Hi Per,

Thank you for the information, I think I have the idea now.

But I tired your example, in Qemulator with Minerva, JS, JM roms, no toolkit 2:
pjw wrote:

Code: Select all

FOR i = 1 to 5 STEP 2, 8:      REMark Note the REMark! (SMSQ/E only!)
..
END FOR i
Which worked the same as in SMSQ/E

Looking at conversion of ZX Spectrum Basic to the QL, the Spectrum Basic is so limiting. I guess that is why the Spectrum had additions like: Beta Basic, MegaBasic etc... to enhance the basic functionality.

My attempts to convert Spectrum games like "Urban Upstart", has stalled little, to make the decision to convert the GOSUBs to Procedures or leave them as they are. IN this case I have a little Z80 machine code to convert to 68000, which should be straight forward.


Regards,

Derek
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by pjw »

Sorry for hijacking this thread! But thats how human conversations run..
Derek, I find it VERY strange that you found that the example above works the same across the board. Just so we're sure we're talking about the same thing:

Code: Select all

for i = 1 to 5 step 2, 8: rem Test
print i,
endfor i
In SBASIC this prints 1 3 5 8. On JS and Minerva it should only print 8! You have to remove the rem statement to get the same behaviour across the board. Right?
We went through all this a couple of weeks back..


Per
dont be happy. worry
- ?
Post Reply