|
Post by B+ on Jun 4, 2020 0:46:18 GMT
If a number were a Triangular one, wouldn't it be great to know which one it was in sequence?
while 1 'Triangular number test b+ 2020-06-03 input "Please Enter a number to test if Triangular, (0 to quit) "; test if test = 0 then end else print triN$(test) wend
function triN$(n) t = (-1 + sqr(1 + 4 * 2 * n))/2 if t = int(t) then triN$ = "Yes, ";n;" is the ";t;" Triangular number." else triN$ = "No, ";n;" is NOT a Triangular number." end if end function
|
|
|
Post by tenochtitlanuk on Jun 4, 2020 20:54:00 GMT
You may be interested in the problems of checking for perfect squares by seeing if their square root is integral using 'int()'. Proper way is to define an 'epsilon' error and check if the absolute value of the difference between sqrt and int( sqrt) exceeds or is smaller than epsilon.
Run the following code in JB/LB- and for interest in LB5, which behaves differently. Basically, square root of a square number- eg 25- may be internally 4.99999.. or 5.0000001.. or possibly 5.0000000 to system max floating pt precision, so int() gives 4 or 5 depending on the number we are using. And, 'using( "####.############", n) will add a further layer of misrepresentation. True for non-integer maths on ANY computer..
for i =1 to 100 t =( i^2)^0.5 if i <>int( t) then print i, using( "######.##########", t), int( t), "NO" else print i, using( "######.##########", t), t, "OK" end if scan next i
end
|
|
|
Post by B+ on Jun 4, 2020 22:37:24 GMT
Yes, gotta say I was worried that SQR was going to mess up the integer math in my t (for test) formula but I did not find any wrong report even for the numbers in billions!
That's why I was checking around 4294967296. BTW where does that number come from? It's not Triangular; I ran a separate code test to confirm.
|
|
|
Post by Rod on Jun 5, 2020 6:42:24 GMT
Maximum 32bit unsigned integer or at least 1 above that.
|
|
|
Post by tsh73 on Jun 5, 2020 8:17:52 GMT
2^32
|
|
|
Post by tenochtitlanuk on Jun 5, 2020 9:32:43 GMT
It's quite an important point in learning to code, isn't it?
Several of my plays on triangular number themes spurred by the LB Challenge #5 involved checking for square numbers and I DID get versions of my code that failed this way.
One ?novel? approach was a kind of Monte Carlo /annealing approach that worked surprisingly quickly- but not of course as fast as the formula methods. Guess n for a particular Tn, then correct it depending if it was high or low. A programming exercise rather than realistically simple and fast, but fun to code.
Same approach as simulated annealing for the Travelling Salesman problem on my site. And under CoViD19 lockdown the idea of travelling town-to-town to sell on the doorstop seems VERY antiquated!
|
|
|
Post by B+ on Jun 5, 2020 12:56:13 GMT
Maximum 32bit unsigned integer or at least 1 above that. 2^32 Is LB not the same as JB with unlimited integer math? Or is this the point where floats or float math get imprecise? say 1 / (2 ^ 32)
|
|
|
Post by B+ on Jun 5, 2020 13:04:06 GMT
OK I did expect this.
OK if this function fails then my challenge is to find the first number where it fails.
function triN$(n) t = (-1 + sqr(1 + 4 * 2 * n))/2 if t = int(t) then triN$ = "Yes, ";n;" is the ";t;" Triangular number." else triN$ = "No, ";n;" is NOT a Triangular number." end if end function
|
|
|
Post by Rod on Jun 5, 2020 13:22:33 GMT
I was just saying what the number was. JB can do big numbers, the issue, if there is one, is that it is built on a 32bit platform, Smalltalk. So some internal registers have limits, LOF() SEEK etc.
Not the same issue as numeric storage.
|
|
|
Post by B+ on Jun 5, 2020 13:56:22 GMT
I was just saying what the number was. JB can do big numbers, the issue, if there is one, is that it is built on a 32bit platform, Smalltalk. So some internal registers have limits, LOF() SEEK etc. Not the same issue as numeric storage. Thanks Rod, knowing LOF() SEEK etc has a limit is good to know. Maybe that's why that number was picked for LB Challenge #5, if case someone wanted to do file work for solution.
|
|
|
Post by tsh73 on Jun 5, 2020 14:49:46 GMT
I believe these challenges are picked from somewhere and as well might first be formulated for some other language (say C/C++) where "32 bit" still holds some sense
|
|
|
Post by carlgundel on Jun 5, 2020 17:26:27 GMT
I was just saying what the number was. JB can do big numbers, the issue, if there is one, is that it is built on a 32bit platform, Smalltalk. So some internal registers have limits, LOF() SEEK etc. Not the same issue as numeric storage. That's right, but there will be a 64-bit version of the Liberty BASIC v5.0 alpha this weekend.
|
|
|
Post by B+ on Jun 5, 2020 18:00:14 GMT
Congratulations Carl!
|
|
|
Post by B+ on Jun 5, 2020 18:13:15 GMT
OK John, I will test some more. Here I create an independent test for Triangular numbers that also return the sequence number of the Triangular number if the test number is one. This is actually a second great solution to LB Challenge #5, specially when I found out how quick you can make a list of 100,000 Triangular Numbers. Using that perfected function I compared results it gets to results the first function gets for first 10 million numbers (one lunch hour run approx) and found 0 discrepancies between the two results. BTW this was after I confirmed the first function verified all Triangular numbers were such and it was finding the proper place in the sequence as well. Here is code for new function and tests of both: ' Triangular Function goes bad.txt b+ 2020-06-05
' Test to see when the triN goes bad, if indeed if goes bad.
' I will produce another independent test for Triangular Numbers that is a sure thing thanks to integer math precision. ' Then I will run numbers from 1 to 10,000,000 to see when the sure thing and the triN$ disagree.
' Make a list of first 100,000 Triangular Number Sequence covers first 5 billion 50 thousand integers dim tri(100000) for n = 1 to 100000 t = t + n tri(n) = t next
'check table and time to create 'for i = 1 to 10 'print tri(i) 'next 'Print "done" ' >>> WOW! that doesn't take long at all! You could do the Challenge from here instead of by formula
' OK check the findN function with known Triangular Numbers (or NOT) ' THIS BTW IS ANOTHER SOLUTION TO LB CHALLENGE #5 while 1 print : print "Testing an alternate and sure function for testing for Triangular Numbers:" input "Enter a number to check if Triangular, (0 to quit) ";test cls if test = 0 then exit while result = findN(test) if result then print test; " is Triangular number: ";result if result = 0 then print test; " is NOT a Triangular number." wend
' test if triN fails on any known Triangular numbers print: print "Testing all Triangular Numbers with triN(i) number, only errors will be noted:" for i = 1 to 100000 'check known Triangular Numbers result = triN(tri(i)) if result <> i then print "The triN function failed to get the correct sequence number for n = ";i next print "Done testing known triangular numbers with triN function."
print: print "Testing all numbers to compare findN(n) function with triN(i) function, only errors will be noted:" 'OK now test the triN$ function with all know Triangular Numbers in tri() dim errors(1000000) for i = 1 to 10000000 'if this is going to fail we should see it by 10 million numbers I would think scan if i mod 100000 = 0 then print "Progress: Testing number ";i TrueN = findN(i) result = triN(i) if result <> TrueN then print "The triN function failed to get the correct sequence number for n = ";i errorsI = errorsI + 1 if errorsI > 1000000 then errorsI = 1000000 : exit for errors(errorsI) = i end if next Print "Done testing findN versus triN functions. Errors found:" if errorsI < 100 then for i = 1 to errorsI print "Error at number: ";errors(i) next else print "Number of errors found were ";errorsI end if Print "End of testing program, Goodbye!"
function findN(n) 'use Binary search to lookup n bottom = 0 : top = 100000 'print tri(top) [tryAgain] scan test = int((top + bottom)/2) if top < bottom then exit function ' we did not find N so not Triangular number if n = tri(test) then findN = test : exit function 'we found a match so it is a Triangular numer and test is the number in sequence if n > tri(test) then bottom = test + 1 if n < tri(test) then top = test - 1 'print bottom, top goto [tryAgain] end function
' modify triN$ to return a the triangular sequence number if n is a triagular number else 0 function triN(n) t = (-1 + sqr(1 + 4 * 2 * n))/2 '<<< we are mainly testing this formula to see if integer math is ruined or NOT by SQR if t = int(t) then triN = t end function
The outcome in last test showed no errors for first 10 million numbers:
|
|
|
Post by tenochtitlanuk on Jun 6, 2020 12:11:20 GMT
Nice bit of thorough testing! My main point was not to criticize your function, just to comment that doing integer tests on floating point number CAN trigger incorrect results. Creating or seeing such code lines always sets my nerves on edge! I got my code working fine, and like you was surprised how fast some methods are. I'm still interested in the different behaviour between JB, LB4 and 5 shown in my post a week ago.. less interested in triangular numbers!
|
|