Thread overview
`acos` returning `-nan`?
Nov 23, 2019
Jonathan Levi
Nov 23, 2019
Timon Gehr
Nov 24, 2019
Jonathan Levi
November 23, 2019
I have a `double` (from a math equation) which when logged is `-1` but when a `acos` it it returns `-nan`?

The `double` has different bit representation than a normal `-1` but I do not see how that is messing up its `acos`.

The `double`'s representation is: true,1023,58720256.

This will reproduce the problem:

```
import std;

void dWrite(double d) {
    import std.stdio;
    import std.conv;
    import std.bitmanip;
    auto dr = DoubleRep(d);
    writeln(d,"\t",dr.sign,"\t", dr.exponent,"\t", dr.fraction);
}
double fromRep(bool sign, ushort exponent, ulong fraction) {
    DoubleRep r;
    r.sign = sign;
    r.exponent = exponent;
    r.fraction = fraction;
    return r.value;
}

void main() {
    double failing = fromRep(true,1023,58720256);
    double lookalike = -1;

    failing.dWrite;
    lookalike.dWrite;

    failing.acos.dWrite;
    lookalike.acos.dWrite;
}
```

Any idea why that is and how I could solve it?

BTW this is the how that number is created: `cos(a.angle)*cos(b.angle) - dot(a.axis*sin(a.angle),(b.axis*sin(b.angle)))`


November 23, 2019
On 23.11.19 18:31, Jonathan Levi wrote:
> ...
> Any idea why that is and how I could solve it?
> 
> BTW this is the how that number is created: `cos(a.angle)*cos(b.angle) - dot(a.axis*sin(a.angle),(b.axis*sin(b.angle)))`
> 
> 

You can print the number at a higher precision:

writefln!"%.16f"(failing); // -1.0000000130385160

I.e., it is actually slightly smaller than -1.
You either have to debug your data source or manually clip the value into the range [-1.0,1.0] before you call acos.
November 24, 2019
On Saturday, 23 November 2019 at 18:09:43 UTC, Timon Gehr wrote:
> You can print the number at a higher precision:
>
> writefln!"%.16f"(failing); // -1.0000000130385160

Oh thanks, that is how that can be done.

> I.e., it is actually slightly smaller than -1.
> You either have to debug your data source or manually clip the value into the range [-1.0,1.0] before you call acos.

Oh, right, duh, thanks.