comparison error
Blitz3D Forums/Blitz3D Programming/comparison error
| ||
Hi! I would like to knew the reason of the uncorrect working of the statement of comparison in the following test: Graphics 800,600 SetBuffer BackBuffer() SetFont LoadFont("MS Sans Serif",20) Local intervalx#[20] Local temp0#,temp1#,temp2#,tempc%,b# x#=14.143 xmax#=15.051 h#=0.242 temp0=13.417 tempc=1 While (temp0<=xmax) temp2=temp0+h intervalx[tempc]=temp2 temp0=temp2 tempc=tempc+1 Wend b=intervalx[3] If x=b Print ""+x+"="+b Else Print ""+x+"<>"+b EndIf WaitKey() End if to insert the next corrections Graphics 800,600 SetBuffer BackBuffer() SetFont LoadFont("MS Sans Serif",20) Local intervalx#[20] Local temp0#,temp1#,temp2#,tempc%,b# x#=14.143 xmax#=15.051 h#=0.242 temp0=13.417 tempc=1 While (temp0<=xmax) temp2=temp0+h intervalx[tempc]=temp2 temp0=temp2 tempc=tempc+1 Wend b=intervalx[3] b=Float(Str(b)) If x=b Print ""+x+"="+b Else Print ""+x+"<>"+b EndIf WaitKey() End then everything is working fine. Ver. 1.98|1.98|1.98 |
| ||
You can use integers if you want to do exact comparisons, floating point numbers by their nature will introduce rounding errors in most of the calculations in your test (difficult to see as Blitz3D rounds floats to 7 decimal places when it converts to strings for the purposes of printing etc.). To use integers, you can use variables that store amounts in units of 1/1000ths, you just need to remember to divide any products by 1000 and insert your own decimal place when printing or use your trick where the string conversion is effectively rounding the inputs before the comparison. If you have to do equality tests with floats you will need to compar the absolute difference of the two numbers with some sort of epsilon value. |
| ||
The Idea with checking the module of difference on small size epsilon value is very terrible. The output code also very crockhood. Can you answer to me on my question? Why two identical numbers are not to each other? I don't scare the inaccuracy, appearing under bigger calculations and built-in system of truncation. In this accident - I compare two identical numbers, peacefully be situated in float. |
| ||
The Idea with checking the module of difference on small size epsilon value is very terrible. As skidracer said, don't EVER perform comparisons on two floats and expect them to be identical at any point.The output code also very crockhood. Can you answer to me on my question: Why two identical numbers are not to each other? I don't scare the inaccuracy, appearing under bigger calculations and built-in system of truncation. In this accident - I compare two identical numbers, peacefully be situated in float. Its not a problem with Blitz. Try it in C, you'll get the same results. As for the above paragraph, didn't understand a word. Crockhood, indeed... :/ |
| ||
At runtime there are no identical numbers unless both are defined at const, which makes the comparision pointless as you know the result upfront. If you compare floats, always compare with an epsilon margin within they must be the same or do not use floating point bug fixed point math or something similar. One thing that will cause further problems if you convert code it, which was mentioned by skid, is that the "old blitz" round the output result, so you don't have full float accuracy. On the other side, this behavior allows float = float checks up to a given point (around .001 - .005 accuracy with "normal" numbers *0 - 1000*) |
| ||
At first I wrote the programm on C++ ( because I work with it longer, than on B3d), but I rewrote it because of specifics of the further using. If you persist - I tomorrow will check this code on MSVC . P.S.: Excuse me for quality of the remarks - I speak english a little. |
| ||
Blitz3D rounds the displayed values to six digits. In your example both numbers are rounded to 14.1430 and then final 0 is removed. So x and b look the same, but in fact x is a little bigger than b. Here are the same numbers, but now you can see the small difference: Graphics 800,600 SetBuffer BackBuffer() Local intervalx#[20] Local temp0#,temp1#,temp2#,tempc%,b# x#=14.143 xmax#=15.051 h#=0.242 temp0=13.417 tempc=1 While (temp0<=xmax) temp2=temp0+h intervalx[tempc]=temp2 temp0=temp2 tempc=tempc+1 Wend b=intervalx[3] ; Blitz3D makes x and b look the same when displayed. Print " x = " + x Print " b = " + b Print ; But x is really a little bigger. Print " x - 14 = " + (x - 14) Print " b - 14 = " + (b - 14) WaitKey() : End |
| ||
2Floyd: thanks. I`m understand now. Use DLL on C++ for calculating =| |
| ||
weird: this doesnt work. but if i use If VertexX(...) = VertexY(...)it works! |
| ||
Isnt this why nassa lost one of the Mars rockets? Thats is rounding error? |
| ||
no, nasa lost one of the rockets because some fool mixed up inches with cm |
| ||
#include<iostream.h> #include<conio.h> template<class abstr> void calc(abstr formal) { cout<<"===\n"; cout<<"for "<<sizeof(formal)<<" bytes"<<endl; abstr intervalx[20]; abstr temp0,temp1,temp2,b; short tempc; abstr x=14.143; abstr xmax=15.051; abstr h=0.242; temp0=13.417; tempc=1; while(temp0<=xmax){ temp2=temp0+h; intervalx[tempc]=temp2; temp0=temp2; tempc++; } b=intervalx[3]; if(x==b) cout<<x<<"="<<b<<endl; else cout<<x<<"!="<<b<<endl; cout<<"===\n"; } void main() { float x1; double x2; calc(x1); calc(x2); cout<<endl; getch(); } Output: === for 4 bytes 14.143!=14.143 === === for 8 bytes 14.143=14.143 === Conclusion: use DLL with 8-byte variable (double) |
| ||
no, nasa lost one of the rockets because some fool mixed up inches with cm Thats a different one. They lost one because of cm/inches they lost another because of imperial screw sizes being different to metric screw sizes and they lost another because of rounding error |
| ||
With double anything is more or less accurate enough. But double is not CPU accelerated as CPU is always opted for INT and FLOAT, so you sacrifice a fair amount of time for nothing. As mentioned above, use fixed point accuracy, then you won't have any problems at all. Thats how large scale engines tend to work. (because float comparision gets quite useless quite fast. Its very accurate around 0, but the large the number gets the less accurate it is. Something fixed point does not have.) |