template T(){
enum a = pow(3.0, 6);
enum b = pow(2, 4.0);
}
unittest
{
alias T!() t;
}
compiling that I get:
/home/b/phobos/std/math.d(2369): Error: Cannot convert &real to ushort* at compile time
/home/b/phobos/std/math.d(3292): called from here: isNaN(y)
/home/b/phobos/std/math.d(3403): called from here: impl(x,cast(real)y)
/home/b/phobos/std/math.d(3239): called from here: pow(cast(real)x,y)
t.d(478): called from here: pow(2,4)
t.d(485): Error: template instance units.T!() error instantiating
I guess technically it's math.isNaN() that's failing?
Comment #1 by iteronvexor — 2012-08-19T22:09:30Z
yup, it's math.isNaN().
template T() {
enum a = isNaN(1.3);
}
unittest
{
alias T!() t;
}
/home/b/phobos/std/math.d(2369): Error: Cannot convert &real to ushort* at compile time
t.d(474): called from here: isNaN(1.3L)
t.d(479): Error: template instance units.T!() error instantiating
God please, will somebody fix this?
Comment #2 by clugdbug — 2012-08-20T08:29:25Z
isNan(x) can be implemented at compile time by:
return (x != x);
It's not exactly the same at run time, because it sets the floating point hardware exception flags, whereas isNaN does not. But there are no exception flags at compile time.
Comment #3 by iteronvexor — 2012-08-20T09:57:19Z
(In reply to comment #2)
> isNan(x) can be implemented at compile time by:
>
> return (x != x);
>
> It's not exactly the same at run time, because it sets the floating point
> hardware exception flags, whereas isNaN does not. But there are no exception
> flags at compile time.
To avoid the casting in isNaN() you would need to know when it's getting called at compile-time and when it's getting called at run-time, correct? There is no way to know that, so we end up with two functions, isNaN() and staticIsNaN(), correct?
bool staticIsNaN(R)(R x) if(isFloatingPoint!R)
{
return x != x;
}
p.s.
why are exception flags being set in a nothrow?
Comment #4 by issues.dlang — 2012-08-20T10:04:39Z
> To avoid the casting in isNaN() you would need to know when it's getting called at compile-time and when it's getting called at run-time, correct? There is no way to know that, so we end up with two functions, isNaN() and staticIsNaN(), correct?
Wrong. __ctfe is true during CTFE and not during runtime. So, you can do
if(__ctfe)
{
//ctfe version
}
else
{
//normal version
}
http://dlang.org/function.html#interpretation
Comment #5 by iteronvexor — 2012-08-20T10:23:00Z
(In reply to comment #4)
great, I didn't know about __ctfe.
Now isInfinity() is failing at compile time because of the same reasons as isNaN(). How do you check to see if a floating point is infinity at compile?
return x == real.infinity
???
Comment #6 by iteronvexor — 2012-08-20T11:46:03Z
(In reply to comment #5)
ok, so pow() calls exp2(), which contains tons of asm statements, which means pow() can't be executed at compile time.
Comment #7 by safety0ff.bugz — 2014-12-31T16:38:13Z
*** This issue has been marked as a duplicate of issue 5227 ***