mpusz / mp-units

The quantities and units library for C++
https://mpusz.github.io/mp-units/
MIT License
998 stars 79 forks source link

Incorrect result: sqrt(x*x) != x for x of type newton, joule, and watt #449

Closed davidgilkaufman closed 1 year ago

davidgilkaufman commented 1 year ago

This function computes sqrt(x*x) and prints out the parts for debugging:

template <typename T>
void identity(const T v1) {
  const auto v2 = v1 * v1;
  const auto v3 = sqrt(v2);

  std::cout << v1 << '\n';
  std::cout << v2 << '\n';
  std::cout << v3 << "\n\n";
};

When run on 1N, 1J, and 1W, it produces 1kN, 1kJ, and 1kW respectively. The function produces correct answers on other units.

  identity(1_q_N); // error! produces 1kN
  identity(1_q_J); // error! produces 1kJ
  identity(1_q_W); // error! produces 1kW
  // the rest produce correct results
  identity(1_q_kg); 
  identity(1_q_kg * 1_q_m);
  identity(1_q_kg / 1_q_s / 1_q_s);

Here is the full output:

1 N
1 m²⋅kg²/s⁴
1 kN

1 J
1 m⁴⋅kg²/s⁴
1 kJ

1 W
1 m⁴⋅kg²/s⁶
1 kW

1 kg
1 kg²
1 kg

1 m⋅kg
1 m²⋅kg²
1 m⋅kg

1 kg/s²
1 kg²/s⁴
1 kg/s²

Full demo: https://godbolt.org/z/9h6vcPo3E

mpusz commented 1 year ago

Thanks for reporting!