boostorg / boostorg/geometry

Issue on AIX with -O2 dealing with acos(-1)

Ouverte
#686 7 commentaires 1 réaction 0 personnes assignées Voir sur GitHub
bug
Langage dominant
C++
Étoiles
517
Forks
232
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

Hi,
On AIX, when compiling Boost 1.69.0 with GCC 8.4 or 9.3, with **-O0**, the test:
```
../bin.v2/libs/geometry/test/algorithms/algorithms_densify.test/gcc-8.3.0/debug/visibility-hidden/algorithms_densify.run…
```
is 100% OK.
However, with **-O2**, the test:
```
test_linear("LINESTRING(1 1, -179 -1)");
```
from:
```
../libs/geometry/test/algorithms/densify.cpp
```
fails with:
```
../libs/geometry/test/algorithms/densify.cpp(129): error: in "test_main_caller( argc, argv )": check g_count < o_count has failed

geometry/test/algorithms/densify.cpp:129:
BOOST_CHECK(g_count < o_count);
```

Instead of seeing: `2 < 5`, I have: `2 < 2` , which is wrong.

After (long) investigation, it appears that the root cause belongs to:

`include/boost/geometry/arithmetic/dot_product.hpp : 39-40`

```
return get(p1) * get(p2)
+ dot_product_maker::apply(p1, p2);
```
which generates an issue in `../boost/geometry/strategies/spherical/densify.hpp`:

```
+89 calc_t const dot01 = geometry::dot_product(xyz0, xyz1);
```

However, that was version 1.69. Looking at current code, I see that it has been deeply modified...

```
calc_t angle01;
formula::interpolate_point_spherical formula;
formula.compute_angle(p0, p1, angle01);
```

Anyway, looking at the new code (lines 30-33):
`include/boost/geometry/formulas/interpolate_point_spherical.hpp`

```
m_xyz0 = formula::sph_to_cart3d(p0);
m_xyz1 = formula::sph_to_cart3d(p1);
CalculationType const dot01 = geometry::dot_product(m_xyz0, m_xyz1);
angle01 = acos(dot01);
```

I think that the issue is still there in 1.72 (and 1.73).

The issue deals with the fact that this code is expecting dot01 to be **EXACTLY -1** .
However, when compiling on AIX with -O2 (GCC 8 or 9 : the same), in 32bit or 64bit, I get:

```
dot01 = f31 **-1.0000000000000002** (raw 0xbff0000000000001)
```

and thus the `acos()` routine returns `NaNQ` since -1,....2 does not belong to [-1,+1], breaking the test.

This is due to some optimized Power assembler instruction being used:
```
fmadd f31,f31,f30,f1
```
instead of `fmul` and then `fadd`, leading to ONE extra bit in the result.

I will investigate why this fmadd operation is not perfectly equivalent to `fmul`+`fadd`.

Anyway, I think that this Boost code expecting to get EXACTLY -1 may be too strong a requirement.
I'm new with Boost. Are there some Boost tools for mitigating such very small discrepancies ?
Thx

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.