Commodore BASIC and binary floating point precision

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












15















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.










share|improve this question



















  • 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















15















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.










share|improve this question



















  • 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













15












15








15


3






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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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












  • 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










3 Answers
3






active

oldest

votes


















14














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.






share|improve this answer






























    9














    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





    share|improve this answer






























      5














      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;






      share|improve this answer


















      • 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










      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
      );



      );













      draft saved

      draft discarded


















      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









      14














      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.






      share|improve this answer



























        14














        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.






        share|improve this answer

























          14












          14








          14







          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.






          share|improve this answer













          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 27 at 14:18









          Peter B.Peter B.

          705212




          705212





















              9














              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





              share|improve this answer



























                9














                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





                share|improve this answer

























                  9












                  9








                  9







                  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





                  share|improve this answer













                  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






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 27 at 16:58









                  Martin ArgeramiMartin Argerami

                  23326




                  23326





















                      5














                      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;






                      share|improve this answer


















                      • 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















                      5














                      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;






                      share|improve this answer


















                      • 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













                      5












                      5








                      5







                      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;






                      share|improve this answer













                      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;







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      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












                      • 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

















                      draft saved

                      draft discarded
















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Displaying single band from multi-band raster using QGIS

                      How many registers does an x86_64 CPU actually have?