1. atom = problem?
- Posted by Jeremy Cowgar <jeremy at cow?ar?com> Apr 28, 2008
- 881 views
Can someone make the following code work?
include misc.e atom a a = tan(10.5) pretty_print(1, a, {0}) printf(1, "\n%.60f\n", a) if a = 1.8498999934219273466595723220962099730968475341796875 then puts(1, "EQUAL\n") else puts(1, "NOT EQUAL\n") end if
The result I get here w/3.2 or 3.1.1 is: $ exu test.e 1.849899993 1.849899993421927346659572322096209973096847534179687500000000 NOT EQUAL I'm having problems with unit testing because of this. Thanks! -- Jeremy Cowgar http://jeremy.cowgar.com
2. Re: atom = problem?
- Posted by Jason Gade <jaygade at y?hoo?com> Apr 28, 2008
- 858 views
Jeremy Cowgar wrote: > > Can someone make the following code work? > > }}} <eucode> > include misc.e > > atom a > a = tan(10.5) > pretty_print(1, a, {0}) > printf(1, "\n%.60f\n", a) > > if a = 1.8498999934219273466595723220962099730968475341796875 then > puts(1, "EQUAL\n") > else > puts(1, "NOT EQUAL\n") > end if > </eucode> {{{ > > The result I get here w/3.2 or 3.1.1 is: > > $ exu test.e > 1.849899993 > 1.849899993421927346659572322096209973096847534179687500000000 > NOT EQUAL > > I'm having problems with unit testing because of this. > > Thanks! > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> It has to do with the limited precision of how floating point numbers are stored in computer memory. You cannot test for perfect equality between two floating point values, just a relative equality (greater or lesser). We had a discussion about it a ways back. http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=6&fromYear=C&toMonth=8&toYear=C&keywords=%22Conversion+error%3F%22 -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
3. Re: atom = problem?
- Posted by Jeremy Cowgar <jeremy at cow?ar?com> Apr 28, 2008
- 804 views
Jason Gade wrote: > > It has to do with the limited precision of how floating point numbers are > stored > in computer memory. So, it has to do with the good old float problem. I had though Euphoria extended the capability to take care of that problem, but that's OK. I guess I can do the unit testing like this:
test_equal("message", sprintf("%.10f", func()), sprintf("%.10f", 1.1293843123))
a bit more work, but no problem. Thanks for clarifying. -- Jeremy Cowgar http://jeremy.cowgar.com
4. Re: atom = problem?
- Posted by CChris <christian.cuvier at a?ricultur?.gouv.fr> Apr 28, 2008
- 811 views
Jeremy Cowgar wrote: > > Can someone make the following code work? > > }}} <eucode> > include misc.e > > atom a > a = tan(10.5) > pretty_print(1, a, {0}) > printf(1, "\n%.60f\n", a) > > if a = 1.8498999934219273466595723220962099730968475341796875 then > puts(1, "EQUAL\n") > else > puts(1, "NOT EQUAL\n") > end if > </eucode> {{{ > > The result I get here w/3.2 or 3.1.1 is: > > $ exu test.e > 1.849899993 > 1.849899993421927346659572322096209973096847534179687500000000 > NOT EQUAL > > I'm having problems with unit testing because of this. > > Thanks! > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> You shouldn't use string conversion to compare atoms, because of the limited precision of floating point numbers in hardware. Use atom_to_float64() in machine.e instead to obtain a sequence of 8 bytes, which is the internal representation of the number. Then comparing these sequences of equal length becomes unambiguous. CChris
5. Re: atom = problem?
- Posted by CChris <christian.cuvier at agri?ul?ure.gouv.fr> Apr 28, 2008
- 801 views
Jeremy Cowgar wrote: > > Jason Gade wrote: > > > > It has to do with the limited precision of how floating point numbers are > > stored > > in computer memory. > > So, it has to do with the good old float problem. I had though Euphoria > extended > the capability to take care of that problem, but that's OK. I guess I can do > the unit testing like this: > > }}} <eucode> > test_equal("message", sprintf("%.10f", func()), sprintf("%.10f", > 1.1293843123)) > </eucode> {{{ > > a bit more work, but no problem. Thanks for clarifying. > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> Not only Eu doesn't extend reals or integers, but it doesn't guarantee that the sum of two integers is an integer - a joke, really! The extension is to be made through an external library, since there is no hardware support to count on anyway. CChris
6. Re: atom = problem?
- Posted by Jeremy Cowgar <jeremy at cow?a?.com> Apr 28, 2008
- 804 views
CChris wrote: > > You shouldn't use string conversion to compare atoms, because of the limited > precision of floating point numbers in hardware. > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 bytes, > which is the internal representation of the number. Then comparing these > sequences > of equal length becomes unambiguous. > I'm not following. Here's what I did:
test_equal("atan2() #1", atom_to_float64(1.283713957607754085898932316922582685947418212890625), atom_to_float64(atan2(10.5, 3.1)))
Here's what I get: failed: atan2() #1. expected: {41,129,149,165,23,138,244,63} but got: {42,129,149,165,23,138,244,63} -- Jeremy Cowgar http://jeremy.cowgar.com
7. Re: atom = problem?
- Posted by Jason Gade <jaygade at ??hoo.com> Apr 28, 2008
- 815 views
Jeremy Cowgar wrote: > > CChris wrote: > > > > You shouldn't use string conversion to compare atoms, because of the limited > > precision of floating point numbers in hardware. > > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 bytes, > > which is the internal representation of the number. Then comparing these > > sequences > > of equal length becomes unambiguous. > > > > I'm not following. Here's what I did: > > }}} <eucode> > test_equal("atan2() #1", > atom_to_float64(1.283713957607754085898932316922582685947418212890625), > atom_to_float64(atan2(10.5, 3.1))) > </eucode> {{{ > > Here's what I get: > > failed: atan2() #1. expected: {41,129,149,165,23,138,244,63} but got: > {42,129,149,165,23,138,244,63} > > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> I think that your sprintf() version would work better, because comparing the output of atom_to_float64() is the same as comparing for absolute equality. Real atoms (as opposed to integer atoms) are stored as doubles and only have about 15 digits of precision. The scanner converts your long string of digits into a double representation. CChris wrote: > Not only Eu doesn't extend reals or integers, but it doesn't guarantee that > the sum of two integers is an integer - a joke, really! > The extension is to be made through an external library, since there is no > hardware support to count on anyway. Unless you are running Euphoria on a very, very old machine (386 class) then you certainly do have hardware FP support. Unless you've built your executable without it. What does "doesn't extend reals or integers" mean? Also, if the sum of two integers exceeds the 31-bit resolution of Euphoria integers then the sum is automatically promoted to a real atom. I don't know why that's a joke. However if a number is defined as an integer and it overflows then you get an error. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
8. Re: atom = problem?
- Posted by Marco Achury <achury at c?ntv.ne?> Apr 28, 2008
- 815 views
This happens not only on Euphoria or on PC. In my student times, I programmed calculator CASIO FX-4000 to solve hydraulic equations. One important step is to calculate friction factor for using iterative method. Sometimes the values never converge in the same value, and mus to check for a small difference instead check for equally. Change your code to: if abs(a - 1.8498999934219273466595723220962099730968475341796875) < 0.000001 -- Use really needed precision then +-+-+-+-+-+-+-+ Marco A. Achury Caracas, Venezuela
9. Re: atom = problem?
- Posted by Jason Gade <jaygade at yahoo?co?> Apr 28, 2008
- 827 views
Marco Achury wrote: > > > This happens not only on Euphoria or on PC. > In my student times, I programmed calculator CASIO FX-4000 to > solve hydraulic equations. One important step is to calculate > friction factor for using iterative method. > > Sometimes the values never converge in the same value, and mus > to check for a small difference instead check for equally. > > Change your code to: > > if abs(a - 1.8498999934219273466595723220962099730968475341796875) > < 0.000001 -- Use really needed precision > then > > +-+-+-+-+-+-+-+ > Marco A. Achury > Caracas, Venezuela Yes, depending on the magnitude of the number, there is a smallest value, epsilon, which can actually change that number when added or subtracted. I had forgotten that I had written limits.e to explore some of these concepts, with Matt's help. You can use the functions "next_higher_atom()" and "next_lower_atom" to see if your result falls into the proper window. Then again, using limits.e, I would probably do it this way:
-- untested expect = 1.849899934219273 -- better to use float64_to_atom() if you know your exact value result = tan(10.5) if abs(expect - result) > get_epsilon(result) then -- fails end if
http://www.rapideuphoria.com/limits.e -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
10. Re: atom = problem?
- Posted by CChris <christian.cuvier at agricult?re.gou?.fr> Apr 28, 2008
- 812 views
Jeremy Cowgar wrote: > > CChris wrote: > > > > You shouldn't use string conversion to compare atoms, because of the limited > > precision of floating point numbers in hardware. > > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 bytes, > > which is the internal representation of the number. Then comparing these > > sequences > > of equal length becomes unambiguous. > > > > I'm not following. Here's what I did: > > }}} <eucode> > test_equal("atan2() #1", > atom_to_float64(1.283713957607754085898932316922582685947418212890625), > atom_to_float64(atan2(10.5, 3.1))) > </eucode> {{{ > > Here's what I get: > > failed: atan2() #1. expected: {41,129,149,165,23,138,244,63} but got: > {42,129,149,165,23,138,244,63} > > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> Ok, I get it better now. The problem may lie in how the interpreter parses the string "1.283713957607754085898932316922582685947418212890625". It won't check all digits. I'll check tonight at home using Mathematica, and will tell you more precisely where the error is. Oh, by the way, do you get the same issue when using atan2(105,31) instead? Because there is some imprecision in 3.1, as you know (same old "penny issue"). CChris
11. Re: atom = problem?
- Posted by Jeremy Cowgar <jeremy at cow??r.com> Apr 28, 2008
- 801 views
CChris wrote: > > Oh, by the way, do you get the same issue when using atan2(105,31) instead? > Because there is some imprecision in 3.1, as you know (same old "penny > issue"). > Some will pass, others will not, so... yes, it has to do with imprecision. -- Jeremy Cowgar http://jeremy.cowgar.com
12. Re: atom = problem?
- Posted by CChris <christian.cuvier at agriculture?gouv.?r> Apr 28, 2008
- 801 views
Jason Gade wrote: > > Jeremy Cowgar wrote: > > > > CChris wrote: > > > > > > You shouldn't use string conversion to compare atoms, because of the > > > limited > > > precision of floating point numbers in hardware. > > > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 > > > bytes, > > > which is the internal representation of the number. Then comparing these > > > sequences > > > of equal length becomes unambiguous. > > > > > > > I'm not following. Here's what I did: > > > > }}} <eucode> > > test_equal("atan2() #1", > > atom_to_float64(1.283713957607754085898932316922582685947418212890625), > > atom_to_float64(atan2(10.5, 3.1))) > > </eucode> {{{ > > > > Here's what I get: > > > > failed: atan2() #1. expected: {41,129,149,165,23,138,244,63} but got: > > {42,129,149,165,23,138,244,63} > > > > > > -- > > Jeremy Cowgar > > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> > > I think that your sprintf() version would work better, because comparing the > output of atom_to_float64() is the same as comparing for absolute equality. > > Real atoms (as opposed to integer atoms) are stored as doubles and only have > about 15 digits of precision. The scanner converts your long string of digits > into a double representation. > > CChris wrote: > > Not only Eu doesn't extend reals or integers, but it doesn't guarantee that > > the sum of two integers is an integer - a joke, really! > > The extension is to be made through an external library, since there is no > > hardware support to count on anyway. > > Unless you are running Euphoria on a very, very old machine (386 class) then > you certainly do have hardware FP support. Unless you've built your executable > without it. > > What does "doesn't extend reals or integers" mean? > There is no builtin provision for integers or reals with more precision bits than what the hardware supports. No 64-bit integers (you could have them on a Pentium SSE2), no 128 bit reals, and so on. No multiprecision (real) arithmetic or calculus, in a nutshell. > Also, if the sum of two integers exceeds the 31-bit resolution of Euphoria > integers > then the sum is automatically promoted to a real atom. I don't know why that's > a joke. > Because integers are stable by addition, regardless of the magnitude of operands. CChris > However if a number is defined as an integer and it overflows then you get an > error. > > -- > A complex system that works is invariably found to have evolved from a simple > system that works. > --John Gall's 15th law of Systemantics. > > "Premature optimization is the root of all evil in programming." > --C.A.R. Hoare > > j.
13. Re: atom = problem?
- Posted by Jason Gade <jaygade at yahoo?co?> Apr 28, 2008
- 803 views
CChris wrote: > > Jason Gade wrote: > > CChris wrote: > > > Not only Eu doesn't extend reals or integers, but it doesn't guarantee > > > that > > > the sum of two integers is an integer - a joke, really! > > > The extension is to be made through an external library, since there is no > > > hardware support to count on anyway. > > > > Unless you are running Euphoria on a very, very old machine (386 class) then > > you certainly do have hardware FP support. Unless you've built your > > executable > > without it. > > > > What does "doesn't extend reals or integers" mean? > > > > There is no builtin provision for integers or reals with more precision bits > than what the hardware supports. No 64-bit integers (you could have them on > a Pentium SSE2), no 128 bit reals, and so on. No multiprecision (real) > arithmetic > or calculus, in a nutshell. Ah, gotcha. > > > Also, if the sum of two integers exceeds the 31-bit resolution of Euphoria > > integers > > then the sum is automatically promoted to a real atom. I don't know why > > that's > > a joke. > > > > Because integers are stable by addition, regardless of the magnitude of > operands. > > CChris So the only thing that I really see with your comments is that Euphoria behaves like most other computer languages out there with regards to numerical limitations. This is not a surprise, and for most applications it's not much of a limitation. And there are libraries in the archive for arbitrary precision arithmetic if that is what your application requires. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
14. Re: atom = problem?
- Posted by Kat <KAT12 at ?oosahs.net> Apr 28, 2008
- 818 views
/me quietly again suggests "string math" (some in archives) or BCD mode in the cpu. Presto, no limits to precision. Switching the cpu to BCD mode, assuming it can be done with the processors Eu will run on, is fastest, of course. Kat
15. Re: atom = problem?
- Posted by Matt Lewis <matthewwalkerlewis at gma?l.?om> Apr 28, 2008
- 812 views
Jeremy Cowgar wrote: > > Jason Gade wrote: > > > > It has to do with the limited precision of how floating point numbers are > > stored > > in computer memory. > > So, it has to do with the good old float problem. I had though Euphoria > extended > the capability to take care of that problem, but that's OK. I guess I can do > the unit testing like this: Actually, it has to do with how floating point numbers are parsed. I recently added scientific.e to parse scientific notation, which gets the full potential precision. Regular floating point values are still parsed the old fashioned way (sufficient for most uses). We could either switch over if the number of digits is too long (have to test to find out where the sweet spot is) or simply use scientific.e for all floating point parsing. Change to scientific notation, and you'll get what you expect. Also, you have way too much precision there. Try this:
include misc.e atom a, b, c, d a = tan(10.5) b = 1.8498999934219273466595723220962099730968475341796875 c = 1.8498999934219273 d = 1.8498999934219273e+0 pretty_print(1, a, {0}) printf(1, "\na %1.16f\n", a) printf(1, " %1.16f\n", 1.8498999934219273466595723220962099730968475341796875 ) printf(1, "b %1.16f\n", b) printf(1, "c %1.16f\n", c) printf(1, "d %1.16f\n", d) if a = 1.8498999934219273466595723220962099730968475341796875e+0 then puts(1, "EQUAL\n") else puts(1, "NOT EQUAL\n") end if
16. Re: atom = problem?
- Posted by Matt Lewis <matthewwalkerlewis at ?m?il.com> Apr 28, 2008
- 798 views
CChris wrote: > > You shouldn't use string conversion to compare atoms, because of the limited > precision of floating point numbers in hardware. > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 bytes, > which is the internal representation of the number. Then comparing these > sequences of equal length becomes unambiguous. Actually, as long as you use scientific notation, it uses the full precision available to 64-bit floating point. We should probably get there will all floating point. Matt
17. Re: atom = problem?
- Posted by Jason Gade <jaygade at yah?o.c?m> Apr 28, 2008
- 805 views
Matt Lewis wrote: > > CChris wrote: > > > > You shouldn't use string conversion to compare atoms, because of the limited > > precision of floating point numbers in hardware. > > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 bytes, > > which is the internal representation of the number. Then comparing these > > sequences of equal length becomes unambiguous. > > Actually, as long as you use scientific notation, it uses the full precision > available to 64-bit floating point. We should probably get there will all > floating point. > > Matt Does it? Can't there still be an off-by-one-or-two-LSBs error when converting from a string to a double? Or for numbers that don't represent perfectly in binary? It's been awhile since I've messed around with this now. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
18. Re: atom = problem?
- Posted by "Euler German" <eulerg at gmail.com> Apr 28, 2008
- 795 views
> On 28 Apr 2008 at 9:39, Jason Gade wrote (maybe snipped): > So the only thing that I really see with your comments is that > Euphoria behaves like most other computer languages out there with > regards to numerical limitations. This is not a surprise, and for most > applications it's not much of a limitation. > > And there are libraries in the archive for arbitrary precision > arithmetic if that is what your application requires. I remember someone made a package for extended math precision in the days of early v2.x -- Antoine something -- from Holland. Maybe this still in the archives. Best, Euler -- _ _| euler f german _| sete lagoas, mg, brazil _| efgerman{AT}gmail{DOT}com _| ----------------------------- _| Reply preferably to the list, _| or to the address above. Thx!
19. Re: atom = problem?
- Posted by Matt Lewis <matthewwalkerlewis at gmail.?om> Apr 28, 2008
- 812 views
Jason Gade wrote: > > Matt Lewis wrote: > > > > Actually, as long as you use scientific notation, it uses the full precision > > available to 64-bit floating point. We should probably get there will all > > floating point. > > > > Does it? Can't there still be an off-by-one-or-two-LSBs error when converting > from a string to a double? Or for numbers that don't represent perfectly in > binary? > > It's been awhile since I've messed around with this now. It's as close as can be made. Look in the source folder for scientific.e. Matt
20. Re: atom = problem?
- Posted by CChris <christian.cuvier at agric?ltur?.gouv.fr> Apr 29, 2008
- 821 views
CChris wrote: > > Jeremy Cowgar wrote: > > > > CChris wrote: > > > > > > You shouldn't use string conversion to compare atoms, because of the > > > limited > > > precision of floating point numbers in hardware. > > > Use atom_to_float64() in machine.e instead to obtain a sequence of 8 > > > bytes, > > > which is the internal representation of the number. Then comparing these > > > sequences > > > of equal length becomes unambiguous. > > > > > > > I'm not following. Here's what I did: > > > > }}} <eucode> > > test_equal("atan2() #1", > > atom_to_float64(1.283713957607754085898932316922582685947418212890625), > > atom_to_float64(atan2(10.5, 3.1))) > > </eucode> {{{ > > > > Here's what I get: > > > > failed: atan2() #1. expected: {41,129,149,165,23,138,244,63} but got: > > {42,129,149,165,23,138,244,63} > > > > > > -- > > Jeremy Cowgar > > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> > > Ok, I get it better now. > The problem may lie in how the interpreter parses the string > "1.283713957607754085898932316922582685947418212890625". > It won't check all digits. > I'll check tonight at home using Mathematica, and will tell you more precisely > where the error is. > Oh, by the way, do you get the same issue when using atan2(105,31) instead? > Because there is some imprecision in 3.1, as you know (same old "penny > issue"). > > CChris In Mathematica 5.5: * N[ArTan[105/31],100] results in a string of the expected length, which the one you parse is a subset of; * N[ArcTan[10.5,3.1],100] outputs only a few decmals. This seems to confirm my guess according to which it is the "3.1" in your test which causes an issue, because 3.1 is not a finite sum of large enough powers of 2. Those sums are the only numbers the hardware can handle loss-less. CChris