π
<-
Chat plein-écran
[^]

CPLua - What is wrong with this while loop?

Programmation et implémentation d'algorithmes.

CPLua - What is wrong with this while loop?

Unread postby MrMagoo » 17 Apr 2021, 16:58

Bonjour! J'espère que vous allez tous bien.
Je suis brésilien et je ne parle pas Français. Je m'excuse et si vous me le permettez, j'écrirai en Anglais dans ce post.

Also, sorry for my bad English too - I'm a Portugues native speaker.

I hope that this forum is active, in order to us talk about this issue.

I have a few calculators and sometimes I like to make some benchmark tests with them. Maybe the "Calculator Olympic Games", if you wish.
I use to figure tests that everyone can play.
But, this time, I tried something different and excluded the non-programable calculators.
My intentions were to analyze the native programming language and also a similar algorithm to them, in order to compare their performance (maybe it is interesting to post the results and the codes in another post).
Well, we all know that the Classpad does not have a native good programming environment when you have performance in mind (even more when you are dealing with numerical analys with a lot of loops). In this way, myself and all the other calculators agreed that we will allow CP330 to use CPLua in substitution of natural Casio Basic.
The benchmark used is to perform Simpson Rule as presented in this link for the Ti-81 (https://www.ticalc.org/pub/81/basic/math/simpson.81) PS: on line 5, the correct code is a capital i instead of one. The corrected instruction is : (B - A) / N -> I
The code was minor adjusted according the possible commands on each calculator.

So, they all have to perform the following definite integral:

e^(x^3), from 0 to 6, with n=1000

It was based on the test presented here: https://www.youtube.com/watch?v=DHRsvSTGiBc

The CPLua code used is:

Code: Select all
--start
function y(x)
  return math.exp(x^3)
end

n = 1000
a = 0 + 0.
b = 6 + 0.
i = (b-a)/n
x = a + 0.
s = 0.0
while ( x < b ) do
  s = s+y(x)
  x = x+i
  s = 4*y(x)+s
  x = x+i
  s = s+y(x)
end
s = s*i/3
print(s)


Ok. All the calculators performed well and provided the same answer (obviously, with their respective performance time).
But CPLua in Classpad did not.
CPLua ignores when x = 6, when it should stop. It iterates one more time, as if the instruction were ( x <= b ) .

I tried everything that I figured that it could be and did not find anything. I tried CPLua 0.8 and 0.10a.

So, I changed the code, reduced the d to 10 and requested an x print before the while end. Just to investigate, the code became:

Code: Select all
n = 10
a = 0 + 0.
b = 6 + 0.
i = (b-a)/n
x = a + 0.
s = 0.0
while ( x < b ) do
  s = s+y(x)
  x = x+i
  s = 4*y(x)+s
  x = x+i
  s = s+y(x)
  print(x)
end
s = s*i/3
print(s)

The output is:
1.2
2.4
3.6
4.8
6
7.2
2.51522462964201e+161
Done.


The 7.2 there is totaly wrong. It is not suposed to be there.
If I change b=5, so it works. If I change b to 6.000001 it works
But if I change b=6.00001 it does not work!!!!


Going a little bit further.
I implemented a function to round the x and the b value in the while condition. The function is (found somewhere, but I forgot to get the link):
Code: Select all
function round( num, numDecimalPlaces )
  local mult = 10^( numDecimalPlaces or 0 )
  return math.floor( num * mult + 0.5 ) / mult
end


And the while condition became:

Code: Select all
while ( round( x ) < round ( b ) ) do


The complete code is:

Code: Select all
function round( num, numDecimalPlaces )
  local mult = 10^( numDecimalPlaces or 0 )
  return math.floor( num * mult + 0.5 ) / mult
end

function y(x)
  return math.exp(x^3)
end

n = 10
a = 0 + 0.
b = 6 + 0.
i = (b-a)/n
x = a + 0.
s = 0.0
while ( round( x ) < round ( b ) ) do
  s = s+y(x)
  x = x+i
  s = 4*y(x)+s
  x = x+i
  s = s+y(x)
  print(x)
end
s = s*i/3
print(s)


It solved the problem but increased 25% in processing time :( .

In another forum, I started the same discussion. Piu58 send some thoughts that I was think about also - maybe a base 10 to base 2 convertion could be the problem. The post is here https://community.casiocalc.org/topic/8069-cplua-what-is-wrong-with-this-while-loop/#entry63773

Taking this road, when a = 0, b = 6, n = 10, the value of i became i = 0.6

0.6 to base 2 is --> 0.6 (base10) = 0.10011001100110011001100110011... (base2) (it is recurring, as a repeating decimal, or in this way, a repeating binary? sorry for the bad english)

When we truncate the binary to the digits presented above and get back to base 10, we get:

0.10011001100110011001100110011 (base2) = 0.59999999962747097015 (base10)

For sure, anything that tries to represent 0.6 in binary and is truncated, will be lower than 0.6.

If we accumulate x with this i lower than 0.6 for 10 times, x will be something lower than 6.

buuuuuuut, when I asked to print (x), the CPLua presents x = 6 (in this way 10 times 0.6 - see the output presented in the begining of this post) and, in this way, it is representing x as 6 in base 10.
I am assuming that when I asked for x, CP330 and CPLua recognized x as 6, and give back to me a '6', so it printed x=6. I was expecting the same behavior in the while condition.

The algorithm in CP330 Casio Basic performs slowly (n = 100 it halts), but make the things right, and stops when x=6. Just in CPLua I got the problem.

So why did CPLua do not stop when x was 6? Does anybody knows why it is happening with CPLua?
Also, does anybody have any suggestion to how to solve it without the round() function in CPLua?
User avatar
MrMagoo
Niveau 1: MD (Membre Débutant)
Niveau 1: MD (Membre Débutant)
Level up: 60%
 
Posts: 2
Joined: 16 Apr 2021, 10:40
Gender: Not specified
Calculator(s):

Re: CPLua - What is wrong with this while loop?

Unread postby Adriweb » 17 Apr 2021, 17:02

Hmm.

FYI, the output with LuaJIT is:

1.2
2.4
3.6
4.8
6


and

1.284216030437e+93
User avatar
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 57.3%
 
Posts: 13370
Images: 1093
Joined: 01 Jun 2007, 00:00
Location: France
Gender: Male
Calculator(s):
Class: (ingénieur)
Twitter: adriweb
GitHub: adriweb

Re: CPLua - What is wrong with this while loop?

Unread postby MrMagoo » 17 Apr 2021, 19:17

AdriWeb, thanks for your reply and to test it on LuaJIT.
Your answer is correct for n=10. It is the same as we get in all other calculators using the programmed method.

All my Tis, HPs and Other Casios did it well too (even my brave fx-700p from the early 80s did it... the beauty take its 8 minutes to peforme the n=1000, but make it wonderfully).

Only ClassPad 330 with CPLua that presented the issue.
It happened with CPLua 0.8 and CPLua 0.10a

It is not necessary to say, but be aware that n=10 is to few divisions to provide a good result to this definite integral.

The correct answer is expected to be something like ≈ 5.963938092×10^91

As you increase the n the better is the results but also increase the processing time (obviously).
I used 10 just to investigate the while loop.

I don't know why it is happening on CPLua. This is the first time that I get something like this.

I searched for the developers activities, but it seems that they are doing other stuff nowadays.
As long as I was able to find, the last developers were Cartix and Binary_man from Planète Casio. Their last login were on 2019 and 2018, respectively.
It is hard to find some active foruns nowadays.

Going further, I inserted the code in tutorialsponint (https://www.tutorialspoint.com/execute_lua_online.php) and removed the round() function from the while condition. The results were the same as in CPLua. See the following picture:

Image

PS: its better to set some decimal cases to the round function. I forgot to do that in the previous example. The following picutre is better example for the use of the programmed CPLua round function.
If I insert the round() function in the while loop, it gets the right answer. See the following

Image

HP-39gII did not presented the problem, but the good old Pascal (online) also presented the same issue. See the following:

Image

The same pascal code, with the round condition:

Image

So the LuaJIT is performing well even without the round() function in the while condition?
User avatar
MrMagoo
Niveau 1: MD (Membre Débutant)
Niveau 1: MD (Membre Débutant)
Level up: 60%
 
Posts: 2
Joined: 16 Apr 2021, 10:40
Gender: Not specified
Calculator(s):


Return to Programmation

Who is online

Users browsing this forum: No registered users and 1 guest

-
Search
-
Social
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Découvre les nouvelles fonctionnalités en Python de l'OS 5.2 pour les Nspire CX II
Découvre les nouvelles fonctionnalités en Python de l'OS 5.5 pour la 83PCE/84+C-T Python Edition
Omega, le fork étendant les capacités de ta NumWorks, même en mode examen !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
509 utilisateurs:
>495 invités
>8 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)

-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)