Bug 3240 – std.numeric.findRoot only works with real

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2009-08-10T03:04:00Z
Last change time
2015-06-09T01:28:05Z
Assigned to
andrei
Creator
bugzilla

Comments

Comment #0 by bugzilla — 2009-08-10T03:04:36Z
Trying to use std.numeric.findRoot with other types than real gives template instantiation errors originating from lines 599 and 560 in numeric.d (DMD 2.031, SVN rev. 1200): 599 if (a==0) c = ieeeMean(copysign(0.0L, b), b); 560 else if (b==0) c = ieeeMean(copysign(0.0L, a), a); If a and b are double, I get the following errors: /usr/local/include/d/phobos2/std/numeric.d(599): Error: template std.math.ieeeMean(T) does not match any function template declaration /usr/local/include/d/phobos2/std/numeric.d(599): Error: template std.math.ieeeMean(T) cannot deduce template function from argument types !()(real,double) /usr/local/include/d/phobos2/std/numeric.d(600): Error: template std.math.ieeeMean(T) does not match any function template declaration /usr/local/include/d/phobos2/std/numeric.d(600): Error: template std.math.ieeeMean(T) cannot deduce template function from argument types !()(real,double) This is because IFTI doesn't work with implicit conversions (bug 1641 and probably others), and std.math.copysign() always returns a real.
Comment #1 by bugzilla — 2009-08-10T03:29:47Z
Um.. like the actual pasted error messages say, the line numbers should be 599 and 600, not 500 and 560. Sorry, don't know how that happened.
Comment #2 by clugdbug — 2009-08-10T04:40:17Z
Good catch. That's caused by a change to the signature of ieeeMean(). Trivially fixable by inserting casts, though arguably copySign should become a templated function. BTW I wrote this code for Tango, it will eventually have a signature change to match the new Phobos style. It predates ranges, for example, even though it's a perfect example of a floating-point range-based algorithm. Thus, it's not as generic as it could be. Don.
Comment #3 by bugzilla — 2009-08-10T04:50:09Z
There's an even simpler fix -- i.e. less typing. :) Since both a, b and c are of type T, this also works: 599 if (a==0) c = ieeeMean!T(copysign(0.0L, b), b); 600 else if (b==0) c = ieeeMean!T(copysign(0.0L, a), a); I've added this fix to my local Phobos. I just tried this for fun, and expected to get an error from trying to implicitly cast real to double. But for some reason it worked.
Comment #4 by andrei — 2009-08-10T07:14:55Z
(In reply to comment #3) > There's an even simpler fix -- i.e. less typing. :) > > Since both a, b and c are of type T, this also works: > > 599 if (a==0) c = ieeeMean!T(copysign(0.0L, b), b); > 600 else if (b==0) c = ieeeMean!T(copysign(0.0L, a), a); > > I've added this fix to my local Phobos. I just tried this for fun, and expected > to get an error from trying to implicitly cast real to double. But for some > reason it worked. Don, sorry, I took this over before seeing you are considering working on it. You may want to take ownership. Thanks!
Comment #5 by clugdbug — 2009-08-11T00:22:18Z
Fixed in SVN commit 1246.