unittest {
import std.math;
double d = 9007199515875288.;
auto r1 = cast (ulong) sqrt (d);
auto r2 = cast (long) sqrt (d);
assert (r1 == r2);
}
$ dmd -checkaction=context -unittest -main -run sub.d
sub.d(6): [unittest] 94906266 != 94906267
1/1 modules FAILED unittests
The expected value is 94906267:
$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=17
sqrt(9007199515875288)
94906266.99999999473164401
For ASM code generated cf. http://forum.dlang.org/post/[email protected]
Comment #1 by dkorpel — 2022-06-21T15:37:21Z
Removing the Phobos dependency:
```
static import core.math;
pragma(inline, true)
double sqrt(double x) @nogc @safe pure nothrow { return core.math.sqrt(x); }
extern(C) void main()
{
double d = 9007199515875288.;
auto r1 = cast (ulong) sqrt(d);
auto r2 = cast (long) sqrt(d);
assert (r1 == r2);
}
```
It doesn't happen when calling core.math.sqrt directly, it looks like the problem manifests because of the inliner:
```
// output of -vcg-ast
extern (C) extern (C) void main()
{
double d = 9.0072e+15;
ulong r1 = cast(ulong)((double x = d;) , sqrt(x));
long r2 = cast(long)((double x = d;) , sqrt(x));
assert(r1 == cast(ulong)r2);
return 0;
}
```
It casts the comma expression to long/ulong, which may trip up the code generator.
Comment #2 by robert.schadek — 2024-12-13T19:23:29Z