Author |
Topic: Possible issue in using 80 bit variables. (Read 619 times) |
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Possible issue in using 80 bit variables.
« Thread started on: Mar 24th, 2015, 7:35pm » |
|
Working on some vector graphic routines, noticed an intermittent anomaly when running it in BBCv6. The supplied program snippet does not produce the same graphics in BBC 5 and 6.
Inserting PRINT as a debug technique seems less usable. The 'List variables utility' displays the correct values, but that is not always enough.(when debugging)
Using the # suffix resolves the issue, but are there any other options? (# after every variable makes the program harder to read and debug).
My concern is in what other situations this error (for the lack of a better word) can occur ?
I know the floating point variable can not represent certain values accurately, is there anything new/added with the 80 bits variable ?
Been thinking about this problem (if there indeed is a problem here) for a month or two, but i am not much closer to a definitive answer.
Any advice is highly appreciated.
Svein
Code: A=100+COSRAD(90)*1000
a#=100+COSRAD(90)*1000
MOVE 100,100 : DRAW 1000,A
MOVE 100,100 : DRAW A,1000
MOVE 104,104 : DRAW 1000,a#+4
MOVE 104,104 : DRAW a#+4,1000
PRINT A,a#
|
|
Logged
|
|
|
|
rtr2
Guest
|
 |
Re: Possible issue in using 80 bit variables.
« Reply #1 on: Mar 24th, 2015, 9:33pm » |
|
on Mar 24th, 2015, 7:35pm, sveinioslo wrote:The supplied program snippet does not produce the same graphics in BBC 5 and 6. |
|
You should not have expected it to. Your program calculates COSRAD90 which is approximately, but not precisely, zero. In fact the values it gives are as follows:
Code:*FLOAT 40: 2.328306437E-10
*FLOAT 64: 6.123031769111887E-17
BB4W v6.0: -2.710505431213761085E-20 You are then converting those values to integers for use in a plotting operation, which gives:
Code:*FLOAT 40: INT(100+COSRAD90*1000) = 100
*FLOAT 64: INT(100+COSRAD90*1000) = 100
BB4W v6.0: INT(100+COSRAD90*1000) = 99 Which is why you see the difference in the graphics. But this is entirely to be expected because the values are being truncated to the next smaller integer, not rounded to the nearest integer. To round you must add 0.5 before using the INT function:
Code:*FLOAT 40: INT(100+COSRAD90*1000+0.5) = 100
*FLOAT 64: INT(100+COSRAD90*1000+0.5) = 100
BB4W v6.0: INT(100+COSRAD90*1000+0.5) = 100 So I see nothing 'anomalous' about this, and it certainly isn't an 'error' (it would be if it did anything different!). It's just that the approximation to COSRAD90 in *FLOAT 40 and 64 modes happens to be a very small positive number and in *FLOAT 80 mode a small negative number, and BBC BASIC always truncates to an integer when plotting.
If you change your code as follows to round correctly, the results are not different between v5 and v6:
Code: A=100+COSRAD(90)*1000
a#=100+COSRAD(90)*1000
MOVE 100,100 : DRAW 1000,A+0.5
MOVE 100,100 : DRAW A+0.5,1000
MOVE 104,104 : DRAW 1000,a#+4.5
MOVE 104,104 : DRAW a#+4.5,1000 Richard.
|
« Last Edit: Mar 24th, 2015, 10:16pm by rtr2 » |
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: Possible issue in using 80 bit variables.
« Reply #2 on: Mar 25th, 2015, 3:42pm » |
|
>You should not have expected it to< Well, i did.
Once i found out why there was a difference in the graphics output, adding 0.5 in the draw command became clear. What i was thinking about for a month or two, was not how to draw the straight line, but more 'what else is affected by the difference in variable precision' , 'what question should i ask, if any' and 'how on earth do i formulate it '. I'm not a good writer in any language.
The uncertainty was more in what other areas there would be a difference between v5 and v6, and how to find out where in a program one needed to apply some adjustment. Given that PRINTing the values did not give much help. I had completely forgotten about the @% format control, almost never used it. Setting it to @%=&130A sorts out that issue.
Ok, so there is a difference in the computed values in v5 and v6.
Running this test, using the COSRAD(90) as an example expression, there must be numerous other examples. Code:
@%=&130A
A=100+COSRAD(90)*1000
PRINT A
PRINT 10000 DIV A
PRINT INT(A)
IF A>=100 THEN PRINT "Yes" ELSE PRINT "No"
Gives in v5: 100.0000003 100 100 Yes
And in v6: 99.99999999999999997 101 99 No
Clearly an issue if the program is to be run in both versions?
I am working on some tools and libraries in some of my spare time, and i want them to function equally in v5 and v6. Now that i know how to read the floating point precision and version, i can probably write some compensating code. Or maybe just remember to use the # suffix, it's not as hard to read the code now, as it was a month or two ago, when i overreacted and placed it after every variable. The program is using both GDI and BBC graphics, so every variable was of the suffixless variant kind. Like this: Code:
IF anti THEN PROC_gdipline(pen,x1,y1,posx,posy) ELSE DRAW posx,posy
Thinking about it (started to write this post a few hours ago), using a proper suffix is probably the easiest route.
Svein
|
|
Logged
|
|
|
|
rtr2
Guest
|
 |
Re: Possible issue in using 80 bit variables.
« Reply #3 on: Mar 25th, 2015, 5:11pm » |
|
on Mar 25th, 2015, 3:42pm, sveinioslo wrote:The uncertainty was more in what other areas there would be a difference between v5 and v6, and how to find out where in a program one needed to apply some adjustment. |
|
I have always emphasised that BB4W v6.00a is potentially incompatible with earlier versions, far more so than all previous 'upgrades'. That's why v5.95a remains available and supported. The help documentation has a section dedicated specifically to the potential incompatibilities:
http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin0.html#compat6
It's true that it doesn't explicitly draw attention to the fact that a transcendental number (like a cosine) must necessarily have a different value if it has a higher precision, but that really should be obvious!
Quote:Given that PRINTing the values did not give much help. |
|
It would have, had you printed the actual values being used by the graphics commands, for example:
Code: X% = 1000
Y% = A
DRAW X%,Y%
PRINT X%,Y% In that case the printed values are the actual integer parameters used by the DRAW statement, and any difference in the drawn graphics would be accompanied by different printed values.
Quote:I had completely forgotten about the @% format control, almost never used it. |
|
There is no value of @% which guarantees that two different binary floating-point values will print differently in decimal. If you want to check whether two numbers are identical or not either use a comparison operator (e.g. <> or ==) or subtract one from the other and print the difference.
Quote:Clearly an issue if the program is to be run in both versions? |
|
I don't know what else I can do other than to point out, as I have always done, that v6 is not fully compatible with v5. You can't have higher-precision numbers without them being different numbers, so if you write a program in such a way that a very tiny change in the value of a variable causes it to behave differently then it probably will!
But if the behaviour of a program depends critically on the precise value of a number, right down to the LSB level, it suggests the program has been written in such a way as to be unduly sensitive and potentially unstable.
Quote:Or maybe just remember to use the # suffix |
|
I must point out that adding a # suffix does not mean that calculations in v6.00a will give the same answers as calculations in v5.95a. Indeed far from it: it's likely that they will give different results; run this code in both versions:
Code: If you need v5 and v6 to give identical numeric results, you must do everything in integer arithmetic. That's the only way.
Richard.
|
« Last Edit: Mar 25th, 2015, 5:33pm by rtr2 » |
Logged
|
|
|
|
Edja
Developer
member is offline


Posts: 60
|
 |
Re: Possible issue in using 80 bit variables.
« Reply #4 on: Mar 25th, 2015, 11:48pm » |
|
Quote:Clearly an issue if the program is to be run in both versions? |
| Does this have to be an issue? In what circumstances would a program have to run in two versions? I think two possibilities cover 99.9% of the cases :
The program is for your personal usage. Then choose your version 5.95a or 6.00a and stick with it.The program is for a number of users and they may not be alligned on one version (they may even have no BB4W on their PC's). Again, choose one version. This time compile the program, then distribute it. They will all see the same result. You are completely in control. Quote:I am working on some tools and libraries in some of my spare time, and i want them to function equally in v5 and v6 |
|
But maybe you want to migrate an existing program from v5.95a to v6.00a. Or you want to use a library you've developed earlier in 5.95a and INSTALL it in a new program with v6.00a. In this case you may have a point. Still I wonder why you would want this ? But I think Richard has documented the possible caveats and the way to avoid any problems in such case.
Eddy
|
|
Logged
|
|
|
|
sveinioslo
Developer
member is offline


Posts: 64
|
 |
Re: Possible issue in using 80 bit variables.
« Reply #5 on: Mar 26th, 2015, 09:17am » |
|
Ok, think i know my issue here, all my projects was started in v5, they are stored in a web folder so that i can work on them from different computers. Two have only v5 installed and two have both, and in the ones with both versions installed, v6 is opened by default. Easily fixed, my lack of understanding the floating point math, is another matter. I have some reading to do.! Thank you, Richard and Eddy for putting me straight.
Svein
|
|
Logged
|
|
|
|
rtr2
Guest
|
 |
Re: Possible issue in using 80 bit variables.
« Reply #6 on: Mar 26th, 2015, 10:02am » |
|
on Mar 25th, 2015, 11:48pm, Edja wrote:Or you want to use a library you've developed earlier in 5.95a and INSTALL it in a new program with v6.00a. |
|
v5.95a and v6.00a share libraries (at least, if they are installed in the default location) and the supplied 'standard' libraries are fully compatible with both versions - with the exception of the undocumented PROC_transpose$() in ARRAYLIB, now hopefully fixed in the version recently uploaded to the group. Indeed v6.00a comes with a couple of updated libraries which are of benefit to v5.95a also.
So it would be highly desirable if user-generated libraries were also compatible with both v5 and v6. I would not expect that to be at all onerous: the vast majority of BBC BASIC programs (I would guess in excess of 99%) require no modification to run perfectly well in v6.00a, and there is no reason why libraries - at least not the sort likely to be written by users - should be any different.
I do not even class Svein's issue as being a 'true' incompatibility between v5 and v6. Rather it is an issue of the program being unduly sensitive to infinitesimal differences in numeric value, which is a characteristic that is worth fixing even if the intention is to run it only in one version.
Richard.
|
|
Logged
|
|
|
|
|