Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:11 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : (MM) strange output

Author Message
wmh9
Newbie

Joined: 09/12/2018
Location: Australia
Posts: 2
Posted: 04:27am 12 Dec 2018
Copy link to clipboard 
Print this post

Using my Colour Maximite to investigate the inner workings of a SDS011 air particulate sensor, I need to count using the following code but get the strange result shown. What am I doing wrong?

count = 2.5
do while count < 9
count = count + 0.1
print count
loop

2.6
2.7
2.8
2.9
3
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
4
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
5
5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
5.9
6
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
7
7.1
7.2
7.3
7.4
7.5
7.59999
7.69999
7.79999
7.89999
7.99999
8.09999
8.19999
8.3
8.4
8.5
8.6
8.7
8.8
8.9
9
9.1



 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 05:51am 12 Dec 2018
Copy link to clipboard 
Print this post

Hi wmh9,

I don't think you are doing anything wrong. I suspect it's a feature of the floating point maths. I'd suggest using the STR$() function but, looking at the manuals, it doesn't seem that the Maximite has the same full featured STR$() function that the Micromite does. Some clever formatting is needed I think.

Do you need fixed decimal points for calculation or display?

Bill

Edited by Turbo46 2018-12-13
Keep safe. Live long and prosper.
 
Chopperp

Guru

Joined: 03/01/2018
Location: Australia
Posts: 1097
Posted: 06:16am 12 Dec 2018
Copy link to clipboard 
Print this post

Hi wmh9 & welcome to the forums

Try this:

count = 2.5
do while count < 9
count = count + 0.1
count$ = format$(count, "%01.1f")
print count$
loop


See the FORMAT$ function of the CMM manual

Brian

Edit. My CMM gives the same results BTW
Edit 2. Code correction (oops)Edited by Chopperp 2018-12-13
ChopperP
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 09:42am 12 Dec 2018
Copy link to clipboard 
Print this post

Hello wmh9

welcome to the shed. The answers above are correct. It is the way floating point numbers are stored internally, they are only ever a very close approximation - in the above examples that are "wrong" they are only 10 millionths of a digit out.

Take a look at this thread from a little while back - it will provide you all the info you could want on this phenomenon
http://www.thebackshed.com/forum/forum_posts.asp?TID=10856 Edited by CaptainBoing 2018-12-13
 
wmh9
Newbie

Joined: 09/12/2018
Location: Australia
Posts: 2
Posted: 11:33am 12 Dec 2018
Copy link to clipboard 
Print this post

Thanks everybody for the fixes. I suppose I am just too used to assembler.
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 03:45pm 12 Dec 2018
Copy link to clipboard 
Print this post

this has caught thousands of programmers over the years and is what the IEEE descibes as "well-meaning ignorance among programmers".

If you want to approach it from the assembler angle, you could mutiply everything by 10 (in your case this is enough) - this is called "fixed point". You'll be familiar with that from assembler. This way it is just your output routines that need to remember to format the output before use, but using INTEGERs instead of FLOATs would provide exact x.1 s just as they would in assembler. Below code is a little rough round the edges but you get the idea; your formatting is used just at the output but the maths works as you expect...



count = 25
do while count < 90
count = count + 1
print count\10;".";count mod 10
loop



If you ever use a floating point maths pack in assembler, you would still encounter the problem of approximation because the FP_Pack is written in or compiled to machine code just as it is with a micromite - The FP routines are inherited from the C compiler (from Microchip) and the C library code ends up in the object code (MMBasic). even in major commercial products it is a pain - google for "Excel rounding error"

There are methods to reduce these problems with different algorithms, but they only shunt the problems elsewhere and it is impossible to get rid entirely. To really kick this to death, read this article. https://en.wikipedia.org/wiki/Floating_point_error_mitigation and this https://en.wikipedia.org/wiki/Floating-point_arithmetic

Edited by CaptainBoing 2018-12-14
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 10:22pm 12 Dec 2018
Copy link to clipboard 
Print this post

I wrote uFormat$() back in the Maximite days.
It still works the same with more recent MMBasics

  Quote   FOR p = -3 TO 3
PRINT uFormat$(6258.990876,p)
NEXT p



FUNCTION uFormat$(x,p)
' given a number (x) and the required number of decimal places (p)
' returns formatted string. Negative and zero p is permitted
LOCAL f$
f$=
STR$(CINT(x*10^p))
IF LEN(f$)<=p THEN
f$=
STRING$(p+1-LEN(f$), "0")+f$
ENDIF
IF p>0 THEN
uFormat$=
LEFT$(f$,LEN(f$)-p)+"."+RIGHT$(f$,p)
ELSEIF p = 0 THEN
uFormat$=f$
ELSE
uFormat$=f$+
STRING$(ABS(p),"0")
ENDIF
END FUNCTION



Jim

edit.
It fails for some conditions with mmbasic V4.5 due to reverting to scientific notation.
Edited by TassyJim 2018-12-14
VK7JH
MMedit
 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 12:18am 13 Dec 2018
Copy link to clipboard 
Print this post

wmh9,

You didn't say whether you wanted the result for display or calculation but changing CaptainBoing's code a little - this will give the result you expected:

count = 25
DO WHILE count < 90
count = count + 1
cnt = count/10
PRINT cnt
LOOP


I'm not sure if it works over a wider range of numbers but it does over the range of numbers you have chosen.

Bill
Keep safe. Live long and prosper.
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025