Commodore BASIC and binary floating point precision
Clash Royale CLAN TAG#URR8PPP
I am mildly curious that though the 6502 provides BCD arithmetic which would be useful for implementing decimal floating point, Commodore BASIC uses, like all (?) Micro-Soft BASIC, binary floating point instead.
Are there any easy example that show precision errors in Commodore BASIC, that would not be present if it would be based on decimal FP?
A classic test of the difference is 0.1 + 0.2 = 0.3
; this evaluates to false in pretty much every modern language (since almost all of them use the IEEE floating point that is built into modern hardware). There is even a website devoted to this oddity: 0.30000000000000004.com
I tried this on a C64 emulator (which uses the same BASIC as the PET) and to my astonishment, it correctly evaluated to true. So did some other obvious tests like 0.1 * 10 = 1
and 0.1 + 0.9 = 1
but they worked as well.
What test would give a wrong answer on Commodore BASIC? That is, I'm not asking for a way to get it to demonstrate rounding errors per se; that much is trivial. I'm asking for a way to get it to give a wrong answer, not because it lacks infinite precision, but specifically for(simple) cases where decimal arithmetic would give the right answer. Some Commodore BASIC (MS-BASIC) equivalent to the 0.1 + 0.2 = 0.3
test on IEEE 754.
basic commodore floating-point
|
show 16 more comments
I am mildly curious that though the 6502 provides BCD arithmetic which would be useful for implementing decimal floating point, Commodore BASIC uses, like all (?) Micro-Soft BASIC, binary floating point instead.
Are there any easy example that show precision errors in Commodore BASIC, that would not be present if it would be based on decimal FP?
A classic test of the difference is 0.1 + 0.2 = 0.3
; this evaluates to false in pretty much every modern language (since almost all of them use the IEEE floating point that is built into modern hardware). There is even a website devoted to this oddity: 0.30000000000000004.com
I tried this on a C64 emulator (which uses the same BASIC as the PET) and to my astonishment, it correctly evaluated to true. So did some other obvious tests like 0.1 * 10 = 1
and 0.1 + 0.9 = 1
but they worked as well.
What test would give a wrong answer on Commodore BASIC? That is, I'm not asking for a way to get it to demonstrate rounding errors per se; that much is trivial. I'm asking for a way to get it to give a wrong answer, not because it lacks infinite precision, but specifically for(simple) cases where decimal arithmetic would give the right answer. Some Commodore BASIC (MS-BASIC) equivalent to the 0.1 + 0.2 = 0.3
test on IEEE 754.
basic commodore floating-point
5
It might be worth to remember that the PET at first was A machine, not a business or home. If at all it was meant as a hobby computer. The differentiation in business or home is something that only evolved later - and with it's missing colour and sound abilities it moved into a (more) business range.
– Raffzahn
Jan 27 at 12:52
1
@Raffzahn True! I tried it on an Apple II emulator just now and it passes the test, though iirc the Apple II ended up using Microsoft BASIC just like Commodore so that's not surprising. I'll try it on some others if I can find emulators with working keyboards.
– rwallace
Jan 27 at 13:00
1
This question is out of the ordinary, and I must admit I really like it. Not at least as it looks for easy repeatable tests over some lengthy explanation. A true Engineering aproach :)) Would you mind to rephrase it (mostly the first paragraph) a bit to focus on the core issue of PET/Commodore FP - as the title already expresses it quite good (maybe also adding "... precision" in the title) I can do as well if you like me to. That way it'll make a great stop for others searching for hints in the same direction.
– Raffzahn
Jan 27 at 14:47
1
@Raffzahn Thanks! The rephrase is an interesting idea, sure, please go ahead.
– rwallace
Jan 27 at 15:25
2
@tofro But that wasn't the question. It's not about if the representation with 10 decimal digits is the same but if the actual numbers are the same. So don't print and visually compare the output but actually compare the numbers and print the outcome of that comparison.
– BlackJack
Jan 27 at 17:56
|
show 16 more comments
I am mildly curious that though the 6502 provides BCD arithmetic which would be useful for implementing decimal floating point, Commodore BASIC uses, like all (?) Micro-Soft BASIC, binary floating point instead.
Are there any easy example that show precision errors in Commodore BASIC, that would not be present if it would be based on decimal FP?
A classic test of the difference is 0.1 + 0.2 = 0.3
; this evaluates to false in pretty much every modern language (since almost all of them use the IEEE floating point that is built into modern hardware). There is even a website devoted to this oddity: 0.30000000000000004.com
I tried this on a C64 emulator (which uses the same BASIC as the PET) and to my astonishment, it correctly evaluated to true. So did some other obvious tests like 0.1 * 10 = 1
and 0.1 + 0.9 = 1
but they worked as well.
What test would give a wrong answer on Commodore BASIC? That is, I'm not asking for a way to get it to demonstrate rounding errors per se; that much is trivial. I'm asking for a way to get it to give a wrong answer, not because it lacks infinite precision, but specifically for(simple) cases where decimal arithmetic would give the right answer. Some Commodore BASIC (MS-BASIC) equivalent to the 0.1 + 0.2 = 0.3
test on IEEE 754.
basic commodore floating-point
I am mildly curious that though the 6502 provides BCD arithmetic which would be useful for implementing decimal floating point, Commodore BASIC uses, like all (?) Micro-Soft BASIC, binary floating point instead.
Are there any easy example that show precision errors in Commodore BASIC, that would not be present if it would be based on decimal FP?
A classic test of the difference is 0.1 + 0.2 = 0.3
; this evaluates to false in pretty much every modern language (since almost all of them use the IEEE floating point that is built into modern hardware). There is even a website devoted to this oddity: 0.30000000000000004.com
I tried this on a C64 emulator (which uses the same BASIC as the PET) and to my astonishment, it correctly evaluated to true. So did some other obvious tests like 0.1 * 10 = 1
and 0.1 + 0.9 = 1
but they worked as well.
What test would give a wrong answer on Commodore BASIC? That is, I'm not asking for a way to get it to demonstrate rounding errors per se; that much is trivial. I'm asking for a way to get it to give a wrong answer, not because it lacks infinite precision, but specifically for(simple) cases where decimal arithmetic would give the right answer. Some Commodore BASIC (MS-BASIC) equivalent to the 0.1 + 0.2 = 0.3
test on IEEE 754.
basic commodore floating-point
basic commodore floating-point
edited Jan 27 at 15:45
Raffzahn
50.9k6120205
50.9k6120205
asked Jan 27 at 12:46
rwallacerwallace
9,036445131
9,036445131
5
It might be worth to remember that the PET at first was A machine, not a business or home. If at all it was meant as a hobby computer. The differentiation in business or home is something that only evolved later - and with it's missing colour and sound abilities it moved into a (more) business range.
– Raffzahn
Jan 27 at 12:52
1
@Raffzahn True! I tried it on an Apple II emulator just now and it passes the test, though iirc the Apple II ended up using Microsoft BASIC just like Commodore so that's not surprising. I'll try it on some others if I can find emulators with working keyboards.
– rwallace
Jan 27 at 13:00
1
This question is out of the ordinary, and I must admit I really like it. Not at least as it looks for easy repeatable tests over some lengthy explanation. A true Engineering aproach :)) Would you mind to rephrase it (mostly the first paragraph) a bit to focus on the core issue of PET/Commodore FP - as the title already expresses it quite good (maybe also adding "... precision" in the title) I can do as well if you like me to. That way it'll make a great stop for others searching for hints in the same direction.
– Raffzahn
Jan 27 at 14:47
1
@Raffzahn Thanks! The rephrase is an interesting idea, sure, please go ahead.
– rwallace
Jan 27 at 15:25
2
@tofro But that wasn't the question. It's not about if the representation with 10 decimal digits is the same but if the actual numbers are the same. So don't print and visually compare the output but actually compare the numbers and print the outcome of that comparison.
– BlackJack
Jan 27 at 17:56
|
show 16 more comments
5
It might be worth to remember that the PET at first was A machine, not a business or home. If at all it was meant as a hobby computer. The differentiation in business or home is something that only evolved later - and with it's missing colour and sound abilities it moved into a (more) business range.
– Raffzahn
Jan 27 at 12:52
1
@Raffzahn True! I tried it on an Apple II emulator just now and it passes the test, though iirc the Apple II ended up using Microsoft BASIC just like Commodore so that's not surprising. I'll try it on some others if I can find emulators with working keyboards.
– rwallace
Jan 27 at 13:00
1
This question is out of the ordinary, and I must admit I really like it. Not at least as it looks for easy repeatable tests over some lengthy explanation. A true Engineering aproach :)) Would you mind to rephrase it (mostly the first paragraph) a bit to focus on the core issue of PET/Commodore FP - as the title already expresses it quite good (maybe also adding "... precision" in the title) I can do as well if you like me to. That way it'll make a great stop for others searching for hints in the same direction.
– Raffzahn
Jan 27 at 14:47
1
@Raffzahn Thanks! The rephrase is an interesting idea, sure, please go ahead.
– rwallace
Jan 27 at 15:25
2
@tofro But that wasn't the question. It's not about if the representation with 10 decimal digits is the same but if the actual numbers are the same. So don't print and visually compare the output but actually compare the numbers and print the outcome of that comparison.
– BlackJack
Jan 27 at 17:56
5
5
It might be worth to remember that the PET at first was A machine, not a business or home. If at all it was meant as a hobby computer. The differentiation in business or home is something that only evolved later - and with it's missing colour and sound abilities it moved into a (more) business range.
– Raffzahn
Jan 27 at 12:52
It might be worth to remember that the PET at first was A machine, not a business or home. If at all it was meant as a hobby computer. The differentiation in business or home is something that only evolved later - and with it's missing colour and sound abilities it moved into a (more) business range.
– Raffzahn
Jan 27 at 12:52
1
1
@Raffzahn True! I tried it on an Apple II emulator just now and it passes the test, though iirc the Apple II ended up using Microsoft BASIC just like Commodore so that's not surprising. I'll try it on some others if I can find emulators with working keyboards.
– rwallace
Jan 27 at 13:00
@Raffzahn True! I tried it on an Apple II emulator just now and it passes the test, though iirc the Apple II ended up using Microsoft BASIC just like Commodore so that's not surprising. I'll try it on some others if I can find emulators with working keyboards.
– rwallace
Jan 27 at 13:00
1
1
This question is out of the ordinary, and I must admit I really like it. Not at least as it looks for easy repeatable tests over some lengthy explanation. A true Engineering aproach :)) Would you mind to rephrase it (mostly the first paragraph) a bit to focus on the core issue of PET/Commodore FP - as the title already expresses it quite good (maybe also adding "... precision" in the title) I can do as well if you like me to. That way it'll make a great stop for others searching for hints in the same direction.
– Raffzahn
Jan 27 at 14:47
This question is out of the ordinary, and I must admit I really like it. Not at least as it looks for easy repeatable tests over some lengthy explanation. A true Engineering aproach :)) Would you mind to rephrase it (mostly the first paragraph) a bit to focus on the core issue of PET/Commodore FP - as the title already expresses it quite good (maybe also adding "... precision" in the title) I can do as well if you like me to. That way it'll make a great stop for others searching for hints in the same direction.
– Raffzahn
Jan 27 at 14:47
1
1
@Raffzahn Thanks! The rephrase is an interesting idea, sure, please go ahead.
– rwallace
Jan 27 at 15:25
@Raffzahn Thanks! The rephrase is an interesting idea, sure, please go ahead.
– rwallace
Jan 27 at 15:25
2
2
@tofro But that wasn't the question. It's not about if the representation with 10 decimal digits is the same but if the actual numbers are the same. So don't print and visually compare the output but actually compare the numbers and print the outcome of that comparison.
– BlackJack
Jan 27 at 17:56
@tofro But that wasn't the question. It's not about if the representation with 10 decimal digits is the same but if the actual numbers are the same. So don't print and visually compare the output but actually compare the numbers and print the outcome of that comparison.
– BlackJack
Jan 27 at 17:56
|
show 16 more comments
3 Answers
3
active
oldest
votes
This example reveals a rounding error under Commodore BASIC V2.0:
A=0.3:B=0.6:IF A+B<>0.9 THEN PRINT A+B-0.9
Running this on a C64 yields a difference of 2.32830644e-10
. Other pairs that fail are 0.4+0.5
, 0.6+0.1
and 0.8+0.1
. Please note that also the order in which the numbers are summed up affects the result. 0.6+0.1-0.7
yields a difference, while 0.1+0.6-0.7
results to 0.
add a comment |
Here is my favourite example for this problem. I often use it to show Excel's mathematical shortcomings, but not surprisingly it works the same in the C64:
10 A = 0.1
20 B = 0.1
30 FOR I = 1 TO 10
40 D = B
50 B = 20 * A - 19 * B
60 PRINT B
70 A = D
80 NEXT I
In every iteration, the algorithm should be doing 20 * 0.1 - 19 * 0.1 = 0.1, but the output on this simulator is
.0999999999
.100000002
.0999999578
.100000845
.0999831052
.100337895
.0932421037
.235157925
-2.60315849
54.1631699
add a comment |
Might I suggest you try 0.11+0.12?
I believe IEEE754 will in fact give the right answer on 0.1+0.2=0.3, using standard single precision. It is, however, not difficult to provoke IEEE754 failures, for instance on 0.11+0.12. The C program below show the raw bin32 representations of the relevant IEEE754 numbers, the program output is:
a :3dcccccd
b :3e4ccccd
a+b:3e99999a
c :3e99999a
IEEE754 copes
a :3de147ae
b :3df5c28f
a+b:3e6b851e
c :3e6b851f
IEEE754 fails
Program:
#include <stdio.h>
#include <stdint.h>
int main( void )
float a = 0.1;
float b = 0.2;
float c = 0.3;
float apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
a = 0.11;
b = 0.12;
c = 0.23;
apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
return 0;
1
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
2
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "648"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f8975%2fcommodore-basic-and-binary-floating-point-precision%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
This example reveals a rounding error under Commodore BASIC V2.0:
A=0.3:B=0.6:IF A+B<>0.9 THEN PRINT A+B-0.9
Running this on a C64 yields a difference of 2.32830644e-10
. Other pairs that fail are 0.4+0.5
, 0.6+0.1
and 0.8+0.1
. Please note that also the order in which the numbers are summed up affects the result. 0.6+0.1-0.7
yields a difference, while 0.1+0.6-0.7
results to 0.
add a comment |
This example reveals a rounding error under Commodore BASIC V2.0:
A=0.3:B=0.6:IF A+B<>0.9 THEN PRINT A+B-0.9
Running this on a C64 yields a difference of 2.32830644e-10
. Other pairs that fail are 0.4+0.5
, 0.6+0.1
and 0.8+0.1
. Please note that also the order in which the numbers are summed up affects the result. 0.6+0.1-0.7
yields a difference, while 0.1+0.6-0.7
results to 0.
add a comment |
This example reveals a rounding error under Commodore BASIC V2.0:
A=0.3:B=0.6:IF A+B<>0.9 THEN PRINT A+B-0.9
Running this on a C64 yields a difference of 2.32830644e-10
. Other pairs that fail are 0.4+0.5
, 0.6+0.1
and 0.8+0.1
. Please note that also the order in which the numbers are summed up affects the result. 0.6+0.1-0.7
yields a difference, while 0.1+0.6-0.7
results to 0.
This example reveals a rounding error under Commodore BASIC V2.0:
A=0.3:B=0.6:IF A+B<>0.9 THEN PRINT A+B-0.9
Running this on a C64 yields a difference of 2.32830644e-10
. Other pairs that fail are 0.4+0.5
, 0.6+0.1
and 0.8+0.1
. Please note that also the order in which the numbers are summed up affects the result. 0.6+0.1-0.7
yields a difference, while 0.1+0.6-0.7
results to 0.
answered Jan 27 at 14:18
Peter B.Peter B.
705212
705212
add a comment |
add a comment |
Here is my favourite example for this problem. I often use it to show Excel's mathematical shortcomings, but not surprisingly it works the same in the C64:
10 A = 0.1
20 B = 0.1
30 FOR I = 1 TO 10
40 D = B
50 B = 20 * A - 19 * B
60 PRINT B
70 A = D
80 NEXT I
In every iteration, the algorithm should be doing 20 * 0.1 - 19 * 0.1 = 0.1, but the output on this simulator is
.0999999999
.100000002
.0999999578
.100000845
.0999831052
.100337895
.0932421037
.235157925
-2.60315849
54.1631699
add a comment |
Here is my favourite example for this problem. I often use it to show Excel's mathematical shortcomings, but not surprisingly it works the same in the C64:
10 A = 0.1
20 B = 0.1
30 FOR I = 1 TO 10
40 D = B
50 B = 20 * A - 19 * B
60 PRINT B
70 A = D
80 NEXT I
In every iteration, the algorithm should be doing 20 * 0.1 - 19 * 0.1 = 0.1, but the output on this simulator is
.0999999999
.100000002
.0999999578
.100000845
.0999831052
.100337895
.0932421037
.235157925
-2.60315849
54.1631699
add a comment |
Here is my favourite example for this problem. I often use it to show Excel's mathematical shortcomings, but not surprisingly it works the same in the C64:
10 A = 0.1
20 B = 0.1
30 FOR I = 1 TO 10
40 D = B
50 B = 20 * A - 19 * B
60 PRINT B
70 A = D
80 NEXT I
In every iteration, the algorithm should be doing 20 * 0.1 - 19 * 0.1 = 0.1, but the output on this simulator is
.0999999999
.100000002
.0999999578
.100000845
.0999831052
.100337895
.0932421037
.235157925
-2.60315849
54.1631699
Here is my favourite example for this problem. I often use it to show Excel's mathematical shortcomings, but not surprisingly it works the same in the C64:
10 A = 0.1
20 B = 0.1
30 FOR I = 1 TO 10
40 D = B
50 B = 20 * A - 19 * B
60 PRINT B
70 A = D
80 NEXT I
In every iteration, the algorithm should be doing 20 * 0.1 - 19 * 0.1 = 0.1, but the output on this simulator is
.0999999999
.100000002
.0999999578
.100000845
.0999831052
.100337895
.0932421037
.235157925
-2.60315849
54.1631699
answered Jan 27 at 16:58
Martin ArgeramiMartin Argerami
23326
23326
add a comment |
add a comment |
Might I suggest you try 0.11+0.12?
I believe IEEE754 will in fact give the right answer on 0.1+0.2=0.3, using standard single precision. It is, however, not difficult to provoke IEEE754 failures, for instance on 0.11+0.12. The C program below show the raw bin32 representations of the relevant IEEE754 numbers, the program output is:
a :3dcccccd
b :3e4ccccd
a+b:3e99999a
c :3e99999a
IEEE754 copes
a :3de147ae
b :3df5c28f
a+b:3e6b851e
c :3e6b851f
IEEE754 fails
Program:
#include <stdio.h>
#include <stdint.h>
int main( void )
float a = 0.1;
float b = 0.2;
float c = 0.3;
float apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
a = 0.11;
b = 0.12;
c = 0.23;
apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
return 0;
1
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
2
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
add a comment |
Might I suggest you try 0.11+0.12?
I believe IEEE754 will in fact give the right answer on 0.1+0.2=0.3, using standard single precision. It is, however, not difficult to provoke IEEE754 failures, for instance on 0.11+0.12. The C program below show the raw bin32 representations of the relevant IEEE754 numbers, the program output is:
a :3dcccccd
b :3e4ccccd
a+b:3e99999a
c :3e99999a
IEEE754 copes
a :3de147ae
b :3df5c28f
a+b:3e6b851e
c :3e6b851f
IEEE754 fails
Program:
#include <stdio.h>
#include <stdint.h>
int main( void )
float a = 0.1;
float b = 0.2;
float c = 0.3;
float apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
a = 0.11;
b = 0.12;
c = 0.23;
apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
return 0;
1
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
2
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
add a comment |
Might I suggest you try 0.11+0.12?
I believe IEEE754 will in fact give the right answer on 0.1+0.2=0.3, using standard single precision. It is, however, not difficult to provoke IEEE754 failures, for instance on 0.11+0.12. The C program below show the raw bin32 representations of the relevant IEEE754 numbers, the program output is:
a :3dcccccd
b :3e4ccccd
a+b:3e99999a
c :3e99999a
IEEE754 copes
a :3de147ae
b :3df5c28f
a+b:3e6b851e
c :3e6b851f
IEEE754 fails
Program:
#include <stdio.h>
#include <stdint.h>
int main( void )
float a = 0.1;
float b = 0.2;
float c = 0.3;
float apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
a = 0.11;
b = 0.12;
c = 0.23;
apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
return 0;
Might I suggest you try 0.11+0.12?
I believe IEEE754 will in fact give the right answer on 0.1+0.2=0.3, using standard single precision. It is, however, not difficult to provoke IEEE754 failures, for instance on 0.11+0.12. The C program below show the raw bin32 representations of the relevant IEEE754 numbers, the program output is:
a :3dcccccd
b :3e4ccccd
a+b:3e99999a
c :3e99999a
IEEE754 copes
a :3de147ae
b :3df5c28f
a+b:3e6b851e
c :3e6b851f
IEEE754 fails
Program:
#include <stdio.h>
#include <stdint.h>
int main( void )
float a = 0.1;
float b = 0.2;
float c = 0.3;
float apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
a = 0.11;
b = 0.12;
c = 0.23;
apb = a+b;
printf( "a :%xn", *(uint32_t *)&a);
printf( "b :%xn", *(uint32_t *)&b);
printf( "a+b:%xn", *(uint32_t *)&apb);
printf( "c :%xn", *(uint32_t *)&c);
if ( a + b == c )
printf( "IEEE754 copesn" );
else
printf( "IEEE754 failsn" );
return 0;
answered Jan 27 at 13:31
BaardBaard
2536
2536
1
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
2
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
add a comment |
1
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
2
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
1
1
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
Ah! I ran the .1+.2 test on a modern machine in double precision; maybe in some sense, single precision is not precise enough to show the difference; CBM BASIC is closer to single precision. But .11+.12=.23 does indeed fail on a C64.
– rwallace
Jan 27 at 14:04
2
2
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
On every half decent implementation, 0.1 + 0.2 will give you something that is very, very close to 0.3. Whether it equals 0.3 is more or less coincidence. The actual precision doesn't matter, double precision will be much much closer to 0.3, but will also make a lot lot smaller difference "not equal".
– gnasher729
Jan 27 at 19:21
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
@gnasher729 Sure... what it equals or not, in the test, is the number produced by the string "0.3", which is 5*2^54 less than 0.3 in double precision, vs 0.1 + 0.2 being 5*2^52 greater.
– Random832
Jan 29 at 4:25
add a comment |
Thanks for contributing an answer to Retrocomputing Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f8975%2fcommodore-basic-and-binary-floating-point-precision%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
It might be worth to remember that the PET at first was A machine, not a business or home. If at all it was meant as a hobby computer. The differentiation in business or home is something that only evolved later - and with it's missing colour and sound abilities it moved into a (more) business range.
– Raffzahn
Jan 27 at 12:52
1
@Raffzahn True! I tried it on an Apple II emulator just now and it passes the test, though iirc the Apple II ended up using Microsoft BASIC just like Commodore so that's not surprising. I'll try it on some others if I can find emulators with working keyboards.
– rwallace
Jan 27 at 13:00
1
This question is out of the ordinary, and I must admit I really like it. Not at least as it looks for easy repeatable tests over some lengthy explanation. A true Engineering aproach :)) Would you mind to rephrase it (mostly the first paragraph) a bit to focus on the core issue of PET/Commodore FP - as the title already expresses it quite good (maybe also adding "... precision" in the title) I can do as well if you like me to. That way it'll make a great stop for others searching for hints in the same direction.
– Raffzahn
Jan 27 at 14:47
1
@Raffzahn Thanks! The rephrase is an interesting idea, sure, please go ahead.
– rwallace
Jan 27 at 15:25
2
@tofro But that wasn't the question. It's not about if the representation with 10 decimal digits is the same but if the actual numbers are the same. So don't print and visually compare the output but actually compare the numbers and print the outcome of that comparison.
– BlackJack
Jan 27 at 17:56