boostorg / boostorg/units

subtraction of dimensionless quantities produce surprising result

Open
#33 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
39
Forks
60
PR merge metrics
No merged PRs in 30d

Description

In a generic environment one needs to write generic function involving integer integrals.
```
template auto f(A a, B b){return 1 - a/b;}
```
Feeding `f(1.,2.)` gives `0.5`.

However if one feeds `f(1.*si::meter, 2.*si::meter)` insted one gets `1` and of type `int`.

This is probably because the dimensionless quantities are implicitly convertible to their value type, which is a good feature. But for some reason in this case this `double` is converted to an `int` before doing the subtraction. The second implicit conversion in seems to be very strong in the language and I don't see a way to solve this in the library (please don't make the conversion `explicit`! that creates many other problems.).

The only solution I found was to define a family of functions specialized for `int`.

```
namespace boost{
namespace units{
template
inline
quantity
operator-(int i,
const quantity& q2)
{
typedef quantity quantity_type;
return quantity_type::from_value(i - q2.value());
}
}}
```

The good news is that this is in principle only needed for int, the bad news is that one need to implement many functions, `(int - dimlessQ)`, `(dimlessQ - int)`, `(int + dimlessQ)`, `(dimlessQ + int)`, `(int * dimlessQ)`, `(dimlessQ * int)`, `(int / dimlessQ)`, `(dimlessQ / int)`.

I would say this is a bug, but that can be controversial. What it is not controversial is that it is surpring because even for totally dimensinless arguments it will not behave like a `double`.

Is there a workaround solution?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.