Inaccurate multiplication in mit-scheme [closed]

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











up vote
5
down vote

favorite












I found out the floating point multiplication in mit-scheme is not accurate, for example,



1 ]=> (* 1991.0 0.1)


will produce



;Value: 199.10000000000002


Could you please help explain the appearance of the weird trailing number “2”?







share|improve this question














closed as off-topic by Michael Homer, muru, Rui F Ribeiro, Fox, meuh Jan 14 at 19:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Requests for learning materials (tutorials, how-tos etc.) are off topic. The only exception is questions about where to find official documentation (e.g. POSIX specifications). See the Help Center and our Community Meta for more information." – Michael Homer, Rui F Ribeiro, meuh
If this question can be reworded to fit the rules in the help center, please edit the question.








  • 2




    floating-point-gui.de
    – Kroltan
    Jan 14 at 16:58






  • 1




    I'm voting to close this question as off-topic because this is not a problem specific to Unix or Linux. Instead it is a mathematics problem relating to the infinite representation of the number one-tenth in base two, which will affect equally any system that uses fixed- or floating-point numbers instead of rationals.
    – Fox
    Jan 14 at 18:03














up vote
5
down vote

favorite












I found out the floating point multiplication in mit-scheme is not accurate, for example,



1 ]=> (* 1991.0 0.1)


will produce



;Value: 199.10000000000002


Could you please help explain the appearance of the weird trailing number “2”?







share|improve this question














closed as off-topic by Michael Homer, muru, Rui F Ribeiro, Fox, meuh Jan 14 at 19:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Requests for learning materials (tutorials, how-tos etc.) are off topic. The only exception is questions about where to find official documentation (e.g. POSIX specifications). See the Help Center and our Community Meta for more information." – Michael Homer, Rui F Ribeiro, meuh
If this question can be reworded to fit the rules in the help center, please edit the question.








  • 2




    floating-point-gui.de
    – Kroltan
    Jan 14 at 16:58






  • 1




    I'm voting to close this question as off-topic because this is not a problem specific to Unix or Linux. Instead it is a mathematics problem relating to the infinite representation of the number one-tenth in base two, which will affect equally any system that uses fixed- or floating-point numbers instead of rationals.
    – Fox
    Jan 14 at 18:03












up vote
5
down vote

favorite









up vote
5
down vote

favorite











I found out the floating point multiplication in mit-scheme is not accurate, for example,



1 ]=> (* 1991.0 0.1)


will produce



;Value: 199.10000000000002


Could you please help explain the appearance of the weird trailing number “2”?







share|improve this question














I found out the floating point multiplication in mit-scheme is not accurate, for example,



1 ]=> (* 1991.0 0.1)


will produce



;Value: 199.10000000000002


Could you please help explain the appearance of the weird trailing number “2”?









share|improve this question













share|improve this question




share|improve this question








edited Jan 14 at 4:21









Jeff Schaller

31.8k848109




31.8k848109










asked Jan 14 at 4:15









TJH

4315




4315




closed as off-topic by Michael Homer, muru, Rui F Ribeiro, Fox, meuh Jan 14 at 19:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Requests for learning materials (tutorials, how-tos etc.) are off topic. The only exception is questions about where to find official documentation (e.g. POSIX specifications). See the Help Center and our Community Meta for more information." – Michael Homer, Rui F Ribeiro, meuh
If this question can be reworded to fit the rules in the help center, please edit the question.




closed as off-topic by Michael Homer, muru, Rui F Ribeiro, Fox, meuh Jan 14 at 19:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Requests for learning materials (tutorials, how-tos etc.) are off topic. The only exception is questions about where to find official documentation (e.g. POSIX specifications). See the Help Center and our Community Meta for more information." – Michael Homer, Rui F Ribeiro, meuh
If this question can be reworded to fit the rules in the help center, please edit the question.







  • 2




    floating-point-gui.de
    – Kroltan
    Jan 14 at 16:58






  • 1




    I'm voting to close this question as off-topic because this is not a problem specific to Unix or Linux. Instead it is a mathematics problem relating to the infinite representation of the number one-tenth in base two, which will affect equally any system that uses fixed- or floating-point numbers instead of rationals.
    – Fox
    Jan 14 at 18:03












  • 2




    floating-point-gui.de
    – Kroltan
    Jan 14 at 16:58






  • 1




    I'm voting to close this question as off-topic because this is not a problem specific to Unix or Linux. Instead it is a mathematics problem relating to the infinite representation of the number one-tenth in base two, which will affect equally any system that uses fixed- or floating-point numbers instead of rationals.
    – Fox
    Jan 14 at 18:03







2




2




floating-point-gui.de
– Kroltan
Jan 14 at 16:58




floating-point-gui.de
– Kroltan
Jan 14 at 16:58




1




1




I'm voting to close this question as off-topic because this is not a problem specific to Unix or Linux. Instead it is a mathematics problem relating to the infinite representation of the number one-tenth in base two, which will affect equally any system that uses fixed- or floating-point numbers instead of rationals.
– Fox
Jan 14 at 18:03




I'm voting to close this question as off-topic because this is not a problem specific to Unix or Linux. Instead it is a mathematics problem relating to the infinite representation of the number one-tenth in base two, which will affect equally any system that uses fixed- or floating-point numbers instead of rationals.
– Fox
Jan 14 at 18:03










2 Answers
2






active

oldest

votes

















up vote
8
down vote



accepted










This quote is from memory and so probably not quite right but it conveys the essence of the problem: "Operating on floating point numbers is like moving piles of sand: every time you do it, you lose a little sand and you get a bit of dirt" (from Kernighan and Plauger's "Elements of programming style" IIRC). Every programming language has that problem.






share|improve this answer


















  • 4




    Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
    – ilkkachu
    Jan 14 at 8:04






  • 1




    @ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
    – NickD
    Jan 14 at 14:30

















up vote
11
down vote













Remember that computers are binary,



No matter how many base 2 digits you’re willing to use, the decimal value 0.1 cannot be represented exactly as a base 2 fraction.



In base2 1/10 is 0.0001100110011001100110011... (repeating forever)



Unfortunately this is result of binary floating point, and any language that uses the FPU will have similar results, like Python.



In [1]: 1991.0 * 0.1
Out[1]: 199.10000000000002

In [2]: 0.1 + 0.2
Out[6]: 0.30000000000000004


This is a Representation error because often decimal fractions cannot be represented exactly as binary (base 2) fractions.



Perl, C, C++, Java, Fortran, Python and scheme will all demonstrate this behavior.






share|improve this answer
















  • 1




    Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
    – TJH
    Jan 14 at 4:55






  • 1




    @TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
    – dave_thompson_085
    Jan 14 at 8:07











  • perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
    – thrig
    Jan 14 at 15:52

















2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
8
down vote



accepted










This quote is from memory and so probably not quite right but it conveys the essence of the problem: "Operating on floating point numbers is like moving piles of sand: every time you do it, you lose a little sand and you get a bit of dirt" (from Kernighan and Plauger's "Elements of programming style" IIRC). Every programming language has that problem.






share|improve this answer


















  • 4




    Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
    – ilkkachu
    Jan 14 at 8:04






  • 1




    @ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
    – NickD
    Jan 14 at 14:30














up vote
8
down vote



accepted










This quote is from memory and so probably not quite right but it conveys the essence of the problem: "Operating on floating point numbers is like moving piles of sand: every time you do it, you lose a little sand and you get a bit of dirt" (from Kernighan and Plauger's "Elements of programming style" IIRC). Every programming language has that problem.






share|improve this answer


















  • 4




    Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
    – ilkkachu
    Jan 14 at 8:04






  • 1




    @ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
    – NickD
    Jan 14 at 14:30












up vote
8
down vote



accepted







up vote
8
down vote



accepted






This quote is from memory and so probably not quite right but it conveys the essence of the problem: "Operating on floating point numbers is like moving piles of sand: every time you do it, you lose a little sand and you get a bit of dirt" (from Kernighan and Plauger's "Elements of programming style" IIRC). Every programming language has that problem.






share|improve this answer














This quote is from memory and so probably not quite right but it conveys the essence of the problem: "Operating on floating point numbers is like moving piles of sand: every time you do it, you lose a little sand and you get a bit of dirt" (from Kernighan and Plauger's "Elements of programming style" IIRC). Every programming language has that problem.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 29 at 21:54

























answered Jan 14 at 4:30









NickD

1,5571312




1,5571312







  • 4




    Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
    – ilkkachu
    Jan 14 at 8:04






  • 1




    @ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
    – NickD
    Jan 14 at 14:30












  • 4




    Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
    – ilkkachu
    Jan 14 at 8:04






  • 1




    @ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
    – NickD
    Jan 14 at 14:30







4




4




Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
– ilkkachu
Jan 14 at 8:04




Yes, well, that's what it feels like if you look too closely (as here). But it's important to remember that the operations in itself aren't fuzzy, it's just that some values can't be represented exactly, so you get the nearest one that can be. For results that can be represented exactly, you get exactly the result you should.
– ilkkachu
Jan 14 at 8:04




1




1




@ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
– NickD
Jan 14 at 14:30




@ilkkachu: indeed. The other answer is probably better in that it goes into the relevant detail. But it is a memorable quote!
– NickD
Jan 14 at 14:30












up vote
11
down vote













Remember that computers are binary,



No matter how many base 2 digits you’re willing to use, the decimal value 0.1 cannot be represented exactly as a base 2 fraction.



In base2 1/10 is 0.0001100110011001100110011... (repeating forever)



Unfortunately this is result of binary floating point, and any language that uses the FPU will have similar results, like Python.



In [1]: 1991.0 * 0.1
Out[1]: 199.10000000000002

In [2]: 0.1 + 0.2
Out[6]: 0.30000000000000004


This is a Representation error because often decimal fractions cannot be represented exactly as binary (base 2) fractions.



Perl, C, C++, Java, Fortran, Python and scheme will all demonstrate this behavior.






share|improve this answer
















  • 1




    Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
    – TJH
    Jan 14 at 4:55






  • 1




    @TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
    – dave_thompson_085
    Jan 14 at 8:07











  • perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
    – thrig
    Jan 14 at 15:52














up vote
11
down vote













Remember that computers are binary,



No matter how many base 2 digits you’re willing to use, the decimal value 0.1 cannot be represented exactly as a base 2 fraction.



In base2 1/10 is 0.0001100110011001100110011... (repeating forever)



Unfortunately this is result of binary floating point, and any language that uses the FPU will have similar results, like Python.



In [1]: 1991.0 * 0.1
Out[1]: 199.10000000000002

In [2]: 0.1 + 0.2
Out[6]: 0.30000000000000004


This is a Representation error because often decimal fractions cannot be represented exactly as binary (base 2) fractions.



Perl, C, C++, Java, Fortran, Python and scheme will all demonstrate this behavior.






share|improve this answer
















  • 1




    Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
    – TJH
    Jan 14 at 4:55






  • 1




    @TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
    – dave_thompson_085
    Jan 14 at 8:07











  • perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
    – thrig
    Jan 14 at 15:52












up vote
11
down vote










up vote
11
down vote









Remember that computers are binary,



No matter how many base 2 digits you’re willing to use, the decimal value 0.1 cannot be represented exactly as a base 2 fraction.



In base2 1/10 is 0.0001100110011001100110011... (repeating forever)



Unfortunately this is result of binary floating point, and any language that uses the FPU will have similar results, like Python.



In [1]: 1991.0 * 0.1
Out[1]: 199.10000000000002

In [2]: 0.1 + 0.2
Out[6]: 0.30000000000000004


This is a Representation error because often decimal fractions cannot be represented exactly as binary (base 2) fractions.



Perl, C, C++, Java, Fortran, Python and scheme will all demonstrate this behavior.






share|improve this answer












Remember that computers are binary,



No matter how many base 2 digits you’re willing to use, the decimal value 0.1 cannot be represented exactly as a base 2 fraction.



In base2 1/10 is 0.0001100110011001100110011... (repeating forever)



Unfortunately this is result of binary floating point, and any language that uses the FPU will have similar results, like Python.



In [1]: 1991.0 * 0.1
Out[1]: 199.10000000000002

In [2]: 0.1 + 0.2
Out[6]: 0.30000000000000004


This is a Representation error because often decimal fractions cannot be represented exactly as binary (base 2) fractions.



Perl, C, C++, Java, Fortran, Python and scheme will all demonstrate this behavior.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 14 at 4:32









gdahlm

50136




50136







  • 1




    Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
    – TJH
    Jan 14 at 4:55






  • 1




    @TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
    – dave_thompson_085
    Jan 14 at 8:07











  • perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
    – thrig
    Jan 14 at 15:52












  • 1




    Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
    – TJH
    Jan 14 at 4:55






  • 1




    @TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
    – dave_thompson_085
    Jan 14 at 8:07











  • perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
    – thrig
    Jan 14 at 15:52







1




1




Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
– TJH
Jan 14 at 4:55




Thanks a lot for your explanation! I understand. Initially, I tried to evaluate the expression in both scheme and clisp, and clisp just printed out 199.1, which made me think that there might be something wrong with scheme. Now, I know that clisp must have returned the round-off of the value, while in memory both clisp and scheme should have the same representation.
– TJH
Jan 14 at 4:55




1




1




@TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
– dave_thompson_085
Jan 14 at 8:07





@TJH: many languages or implementations round off floating point values when displayed -- or more exactly when converted to textual form, as is normally done for display and sometimes for other purposes.
– dave_thompson_085
Jan 14 at 8:07













perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
– thrig
Jan 14 at 15:52




perl6 -e 'say 1991.0 * 0.1' gives 199.1 and perl6 -e 'say( 0.3 - 0.2 - 0.1 == 0 )' gives True. This is unlike Perl5, C, C++, Java, etc
– thrig
Jan 14 at 15:52


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?