digitalmars.D.bugs - [Issue 8476] New: float comparison operand not truncated from real
- d-bugmail puremagic.com (82/82) Jul 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (15/15) Jul 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (12/14) Jul 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (11/18) Jul 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (8/8) Jul 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (14/21) Jul 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (18/24) Jul 31 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (19/19) Oct 15 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (10/10) Oct 16 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (17/17) Oct 16 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8476
- d-bugmail puremagic.com (10/10) May 28 2013 http://d.puremagic.com/issues/show_bug.cgi?id=8476
http://d.puremagic.com/issues/show_bug.cgi?id=8476 Summary: float comparison operand not truncated from real Product: D Version: D2 Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: ellery-newcomer utulsa.edu --- Comment #0 from Ellery Newcomer <ellery-newcomer utulsa.edu> 2012-07-30 14:28:26 PDT --- The following code produces different results on a comparison. The problem is in fitnessCompare; it looks like one of the two operands has float precision, while the other has real precision. assembly dump: 08065710 <_D19travelling_salesman4mainFZv14fitnessCompareMFS19travelling_salesman10chromosomeS19travelling_salesman10chromosomeZb>: 8065710: 55 push ebp 8065711: 8b ec mov ebp,esp 8065713: 83 ec 10 sub esp,0x10 8065716: ff 75 14 push DWORD PTR [ebp+0x14] 8065719: ff 75 10 push DWORD PTR [ebp+0x10] 806571c: e8 27 00 00 00 call 8065748 <_D19travelling_salesman7fitnessFNaxS19travelling_salesman10chromosomeZf> 8065721: ff 75 0c push DWORD PTR [ebp+0xc] 8065724: ff 75 08 push DWORD PTR [ebp+0x8] 8065727: d9 5d f0 fstp DWORD PTR [ebp-0x10] 806572a: e8 19 00 00 00 call 8065748 <_D19travelling_salesman7fitnessFNaxS19travelling_salesman10chromosomeZf> 806572f: d9 45 f0 fld DWORD PTR [ebp-0x10] 8065732: d9 c9 fxch st(1) 8065734: de d9 fcompp 8065736: df e0 fnstsw ax 8065738: 9e sahf 8065739: b8 01 00 00 00 mov eax,0x1 806573e: 7a 02 jp 8065742 <_D19travelling_salesman4mainFZv14fitnessCompareMFS19travelling_salesman10chromosomeS19travelling_salesman10chromosomeZb+0x32> 8065740: 72 02 jb 8065744 <_D19travelling_salesman4mainFZv14fitnessCompareMFS19travelling_salesman10chromosomeS19travelling_salesman10chromosomeZb+0x34> 8065742: 31 c0 xor eax,eax 8065744: c9 leave 8065745: c2 10 00 ret 0x10 actual code: import std.stdio; import std.random; import std.array; import std.math; struct city{ int x; int y; } struct chromosome{ city[] dna; } void main(){ bool fitnessCompare(chromosome first,chromosome second){ return fitness(first)>fitness(second); } auto less = &fitnessCompare; auto z = chromosome([city(0, 10), city(25, 25), city(10, 65), city(50, 50), city(75, 30), city(20, 0)]); auto f = fitness(z); writeln("fitness(z) > fitness(z) ?",f > f); writeln("fitness(z) > fitness(z) ?",less(z,z)); } float fitness(const chromosome victim) pure{ const city[] cities=city(0,0) ~ victim.dna ~ city(0,0); //we need to start from home and return to home float travelled=0f; for(int x=0;x<cities.length-1;x++) travelled+=distance(cities[x],cities[x+1]); //writeln(100/travelled); return 100/travelled; } float distance(city from,city to) pure{ return sqrt(cast(float)(pow(to.x-from.x,2) + pow(to.y-from.y,2))); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla digitalmars.com --- Comment #1 from Walter Bright <bugzilla digitalmars.com> 2012-07-30 14:44:36 PDT --- I'm not sure what the issue is here. Can you point to what you think it should be doing? Also, the compiler is allowed to not truncate reals to floats when doing comparisons, even if it is typed as a float. This is a feature, not a bug. The compiler is always allowed to use a higher precision for intermediate calculations than the source is typed. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bearophile_hugs eml.cc --- Comment #2 from bearophile_hugs eml.cc 2012-07-30 15:09:48 PDT --- (In reply to comment #1)The compiler is always allowed to use a higher precision for intermediate calculations than the source is typed.A disadvantage of this is loss of floating point reproducibility across compilers, maybe similar to using the "-ffast-math" of GCC. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 --- Comment #3 from Ellery Newcomer <ellery-newcomer utulsa.edu> 2012-07-30 16:09:48 PDT --- (In reply to comment #1)I'm not sure what the issue is here. Can you point to what you think it should be doing? Also, the compiler is allowed to not truncate reals to floats when doing comparisons, even if it is typed as a float. This is a feature, not a bug. The compiler is always allowed to use a higher precision for intermediate calculations than the source is typed.my diagnosis is probably wrong, but writeln("fitness(z) > fitness(z) ?",f > f); writeln("fitness(z) > fitness(z) ?",less(z,z)); are printing out different results when they should be printing the same thing. dmd 2.059, 32 bit only. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 --- Comment #4 from Walter Bright <bugzilla digitalmars.com> 2012-07-30 20:58:21 PDT --- f is of type float. z is of type chromosome. Where are they the same types? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 --- Comment #5 from Walter Bright <bugzilla digitalmars.com> 2012-07-30 21:00:54 PDT --- (In reply to comment #2)(In reply to comment #1)D made the decision early on that: more precision == better and that any program that relied on results being less accurate was a faulty program. Use of float should be for: 1. speed 2. less memory consumption and *never* for reduced precision. float guarantees a *minimum* precision, not a maximum. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------The compiler is always allowed to use a higher precision for intermediate calculations than the source is typed.A disadvantage of this is loss of floating point reproducibility across compilers, maybe similar to using the "-ffast-math" of GCC.
Jul 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 --- Comment #6 from bearophile_hugs eml.cc 2012-07-31 02:12:51 PDT --- (In reply to comment #5)D made the decision early on that: more precision == better and that any program that relied on results being less accurate was a faulty program.You are right, of course, and such problems are common: http://www.parashift.com/c++-faq-lite/floating-point-arith2.html On the other hand I remember one of my D programs not being as efficient as a very similar C++ program just because the C++ code used float-based operations instead of double-based ones, despite me typing float every FP variable and tagging with "f" every floating point literal. In some cases std.math return a double even if all it's required is a float, and the useless computation of the extra precision slows down the code compared to the C++ code that uses functions that return only a float precision. I presume the float versions of some functions perform less iterations to compute the smaller number of precision digits, and this makes them faster. And in some way std.math was unable to let me use the faster float version. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 31 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 --- Comment #7 from Ellery Newcomer <ellery-newcomer utulsa.edu> 2012-10-15 17:16:10 PDT --- Alright, let's try this again, except with me being comprehensible this time. There is one thing happening here, and that is float f; ... bool result = f < f; It is happening in two places: main, and main.fitnessCompare. In both places, f has the same value (4.2 or something). In both places, f is the result of the pure function fitness. result should always be false for a non-{nan, inf, other floating point screwball} In main.fitnessCompare, result is true. This is wrong. Running the debugger, it appeared to me that one of the two operands to the floating point compare in main.fitnessCompare had 80 bits of precision, while the other only had 64 (or maybe 64 and 32, I don't remember). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 15 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 Maxim Fomin <maxim maxim-fomin.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |monarchdodra gmail.com --- Comment #8 from Maxim Fomin <maxim maxim-fomin.ru> 2012-10-16 09:04:45 PDT --- *** Issue 8745 has been marked as a duplicate of this issue. *** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 16 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 Maxim Fomin <maxim maxim-fomin.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |maxim maxim-fomin.ru --- Comment #9 from Maxim Fomin <maxim maxim-fomin.ru> 2012-10-16 09:18:02 PDT --- Regardless of whether (when comparing floats with reals) compiler should compare with full or truncated to smaller type precision, current behavior seems to be inconsistent with spec. According to the spec in section "Equality Expressions" floating point types are compared bitwise. This means that if two floats are compared, compiler need not care about extra precision but currently it compares 32 bit with 80 bit (issue is better revealed in 8745). But if this is feature and not a bug, spec should be changed and better explain the issue. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 16 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8476 Vladimir Panteleev <thecybershadow gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |thecybershadow gmail.com --- Comment #10 from Vladimir Panteleev <thecybershadow gmail.com> 2013-05-28 10:05:10 EEST --- *** Issue 10187 has been marked as a duplicate of this issue. *** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 28 2013