View previous topic :: View next topic |
Author |
Message |
P_Santos
Joined: 07 Jul 2011 Posts: 114
|
Posted: Wed Apr 21, 2021 10:12 pm Post subject: Problem with Single variable |
|
|
Hi,
Below a piece of code to show the problem i have if i use single variables,
if i use instead, double variables it works correct
Anyone know what i make wrong??
Thank for any help
Regards
P_Santos
Code: |
$hwstack = 70
$swstack = 70
$framesize = 70
$regfile = "m88def.DAT"
'# RC Osc Intern 8MHZ
$crystal = 8000000
'
Config Single = Scientific , Digits = 5 'to show the Problem dif2 = 0.699995
'Config Single = Scientific , Digits = 3 'print correct dif2 = 0.700 but not work on the If statment!
'
Dim Xc_ As Double , Saved_x As Double , Dif2 As Double , Irthreshold As Double
'Dim Xc_ As Single , Saved_x As Single , Dif2 As Single , Irthreshold As Single
Again:
Xc_ = 840
Dif2 = 0.70000
Irthreshold = 0.70000
Saved_x = Xc_ - Irthreshold
Print "Saved_x " ; Saved_x ; " dif2x " ; Dif2
'-----------------------------
Dif2 = Xc_ - Saved_x 'Problem with Single variable!!!!
Print "DIF2 " ; Dif2 ; " xc_ " ; Xc_ ; " Saved_x " ; Saved_x
'-----------------------------
Print "xc_ " ; Xc_ ; " dIF2 " ; Dif2 ; " TH " ; Irthreshold ; " Saved_x " ; Saved_x
If Dif2 >= Irthreshold Then
Print "OK Go " ; Dif2
Else
Print "Again " ; Dif2
Goto Again
End If
End
|
(BASCOM-AVR version : 2.0.8.3 , Latest : 2.0.8.3 ) |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Thu Apr 22, 2021 9:34 am Post subject: |
|
|
Doing math with floating point values is always "non-precise". The obvious example in the decimal world is: 3 * (1/3) = 0.9999999999. As computers work binary rounding errors may occur on places where decimals are precise. That is why 840-0.7 = 839.0000005 or so.
If you use config single or config double only the print or str() statements are rounding to the given decimals - the value is not changed.
It is a good practice when comparing calculated floating point values to allow an error margin. So instead
Code: | if floatvar_A = floatvar_B then
(...)
end if
|
use something like
Code: | if abs(floatvar_A - floatvar_B) < 0.0005 then
(...)
end if |
(this is not BASCOM syntax - just to show the idea...) |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Thu Apr 22, 2021 9:38 am Post subject: |
|
|
your problems seems that you did not read the help. maybe because it is in English. But some good translators exist. also this forum has a search function, you could try it. although i admit in many cases it will give a lot of posts.
anyway it is explained in the help. if there are questions about the help just ask here.
Also you post some code which is very good. but you do not write what is wrong in your opinion.
Just read the LANGUAGE FUNDAMENTALS in the help (you get there when you look for SINGLE) and it should become clear why the SINGLE works as it does. _________________ Mark |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Thu Apr 22, 2021 9:43 am Post subject: |
|
|
and i like to add that you can scale an integer :
Code: | Dim XC ,dif2 as ling
Xc_ = 8400
Dif2 = 7
|
here i multiplied with a factor of 10. but it could be 100 or 1000 too.
then use format() to get the representation you like. _________________ Mark |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Apr 22, 2021 10:00 am Post subject: Re: Problem with Single variable |
|
|
P_Santos wrote: | Anyone know what i make wrong?? |
Your error is, that your question is not sharp enough, you do not tell what you expect.
Single is a variable with huge range but limited accuracy, and as bigger its value grows, as more accuracy of the decimal places gets lost.
Ideally your code would behave like that:
840 - 0.7 = 839.3
840 - 839.3 = 0.7
0.7 >= 0.7 ? = TRUE
Actually if you assign 840.0 to a single, already at the very point of assignment it may not represented internally with this exact value.
The same with 0.7, which leads to the subtraction result of 0.700000000000045, while 0.7 would be expected.
Your final if/else test is moot however, as 0.700000000000045 >= 0.7 branches the same as 0.7 >= 0.7
Also from your question it comes not clear, whether or not you misunderstand this config:
Code: | Config Single = Scientific , Digits = 5 |
which is nothing else than eye-candy, respective print-candy, it alters only the representation against the "outer world", or in case of a conversion.
It does not affect internal representation of the value or calculations therewith.
I did not test Doubles, it may work different for them as Double-values sport twice the amount of bits for mantissa and exponent, also the Double-routines may apply some rounding,
Comparing any floats (Single/Double) is difficult, if you can not avoid it, you need to apply some rounding or truncation. |
|
Back to top |
|
|
SZTRAD
Joined: 30 Dec 2019 Posts: 165
|
Posted: Thu Apr 22, 2021 12:09 pm Post subject: |
|
|
Hi
you can understand what the guys are trying to tell you by adjusting your program a bit according to what Mark sent you.
Run the simulator and look at the results on the console. Interpreting what's after the decimal point is always problematic, but it's logical.
Code: |
$hwstack = 70
$swstack = 70
$framesize = 70
$regfile = "m88def.DAT"
'# RC Osc Intern 8MHZ
$crystal = 8000000
'
Config Single = Scientific , Digits = 5 'to show the Problem dif2 = 0.699995
'Config Single = Scientific , Digits = 3 'print correct dif2 = 0.700 but not work on the If statment!
'
'Dim Xc_ As Double , Saved_x As Double , Dif2 As Double , Irthreshold As Double
Dim Xc_ As Single , Saved_x As Single , Dif2 As Single , Irthreshold As Single
Dim Xc_z As Single , Saved_xz As Single , Dif2z As Single , Irthresholdz As Single
Again:
Xc_ = 840
Dif2 = 0.70000
Irthreshold = 0.70000
Saved_x = Xc_ - Irthreshold
Print "Saved_x " ; Saved_x ; " dif2x " ; Dif2
xc_z=xc_*10000
Saved_xz=Saved_x*10000
Dif2z=Dif2*10000
Irthresholdz=Irthreshold*10000
Print "xc_z " ; Xc_z ; " dIF2z " ; Dif2z ; " THz " ; Irthresholdz ; " Saved_xz " ; Saved_xz
'-----------------------------
Dif2 = Xc_ - Saved_x
Dif2z = Xc_z - Saved_xz 'Problem with Single variable!!!!
Print "DIF2 " ; Dif2 ; " xc_ " ; Xc_; " Saved_x " ; Saved_x
Print "DIF2z " ; Dif2z ; " xc_z " ; Xc_z; " Saved_xz " ; Saved_xz
'-----------------------------
Print "xc_ " ; Xc_ ; " dIF2 " ; Dif2 ; " TH " ; Irthreshold ; " Saved_x " ; Saved_x
If Dif2 >= Irthreshold Then
Print "OK Go " ; Dif2
Else
Print "Again " ; Dif2
Goto Again
End If
End |
RS |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Apr 22, 2021 3:30 pm Post subject: |
|
|
SZTRAD wrote: | what the guys are trying to tell |
I was not trying to tell, as the phrase 'trying to' stands somehow for a rather failing approach.
I actually did tell.
Quote: | as bigger its value grows, as more accuracy of the decimal places gets lost |
Maybe a proverb fits here: Everything was already said, but not by everyone |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Thu Apr 22, 2021 3:43 pm Post subject: |
|
|
MWS wrote: |
I was not trying to tell, as the phrase 'trying to' stands somehow for a rather failing approach.
I actually did tell.
|
please do not make this a word game. _________________ Mark |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Apr 22, 2021 4:18 pm Post subject: |
|
|
albertsm wrote: | please do not make this a word game. |
Had not the slightest intention to play word games.
I do not like that somebody degrades other posters messages for the purpose of creating a springboard for his own message.
My message was also not the kind needing explanation, interpretation or translation.
I made a two second break before start writing my previous post, these two seconds because English is not sztrad's native language and he may not understand that his words are degrading other members efforts.
Beginning the third second I thought, that he will be able to stand my cottony style post.
If not - I will call him Mimosa pudica in the future |
|
Back to top |
|
|
SZTRAD
Joined: 30 Dec 2019 Posts: 165
|
Posted: Fri Apr 23, 2021 6:44 am Post subject: |
|
|
Hi
I didn't mean to degrade anyone's post. If it came across that way I apologize.
In our country, the saying is once shown is better than 20 times explained.
I'm not offensive or catchy. I meet a lot of different people and try to get along with everyone.
MWS I appreciate your knowledge and I will not reply anywhere you admit to it,so Mark doesn't have to delete posts.
Have a nice day |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Apr 23, 2021 7:33 am Post subject: |
|
|
SZTRAD, I do not have qualms against you, imho you are a knowledgeable member and I appreciate your posts.
Your intention of showing the effect of limited accuracy with Single was laudable, but it would have been laudable already by itself, there was no need to use other members efforts (yes, I put efforts in my posts, trying always to be technical correct) as an argument in the very sense of: 'Nice try guys, but now that's me, I'll explain it to the TO so he understands'.
And while I'm (most times) technical correct, I do miss any heightened level of courtesy, I am more the guy of telling it clear, pointed and direct.
If this annoys some members, my apologies, but I won't step back from this beloved behavior, thus it likely will happen again.
Be assured, it is never meant as harsh and personal as it may sound. |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Fri Apr 23, 2021 4:57 pm Post subject: |
|
|
My Lord,
A Kumbaya moment to be memorialized in the annals of the BASCOM Forum.
E |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Apr 23, 2021 5:59 pm Post subject: |
|
|
enniom wrote: | A Kumbaya moment |
|
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Fri Apr 23, 2021 6:23 pm Post subject: |
|
|
I had to search for a while to find out what Ennion meant
Paroles de la chanson Kumbaya par Joan Baez
Kumbaya, my Lord, kumbaya
Kumbaya, my Lord, kumbaya
Kumbaya, my Lord, kumbaya
Oh, Lord, kumbaya
-----------------------------
my poor lord !
yes sometimes our friends are a bit dry with their direct comments
but that is the charm of this forum
-----------------------------
I had the same problem with the "singles" I had done the calculations on an Excel sheet and the results were very different when I redid the calculations with Bascom
then I discovered the doubles
Have a nice Week-end
JP _________________ pleasure to learn, to teach, to create |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Sat Apr 24, 2021 2:07 am Post subject: |
|
|
Floating point always has rounding errors. Doing calcs in double precision is one way, but it really only masks the problem by pushing it down several decimal places, at the expense of very much longer execution time.. Where you only want the precision that singles can give, then using the Format statement on your result will give the nearest correct output display, regardless of the internal representation. "Real World" mearurements like readings from sensors are only very rarely accurate to more that a few decimal places, so it makes sense to use singles on these, and Format appropriately, rather than doubles.
Excel on a 64 bit machine allows 64 bits of precision, or 2^64, approx 10^20, or 20 digits of precision in decimal integers. I suspect that it uses this for almost all calcs for speed reasons, and only switches to floating point when necesary. ( And of course the machine it runs on also has a FP processor, so can drastically cut the execution time anyway ) _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|