## #10270 closed Bugs (fixed)

# square root of boost units scaled_unit fails to compile

Reported by: | Owned by: | Matthias Schabel | |
---|---|---|---|

Milestone: | To Be Determined | Component: | units |

Version: | Boost Development Trunk | Severity: | Problem |

Keywords: | scale | Cc: |

### Description

I have created a scaled unit to handle micro meters:

typedef make_scaled_unit<si::length, scale<10, static_rational<-6> > >::type micro_meter_unit;

Everything works as expected:

quantity<si::length, double> some_meter = 10 * si::meter; quantity<micro_meter_unit, double> some_mu_meter = static_cast<quantity<micro_meter_unit, double>>(some_meter); std::cout << "some_meter^2 = " << some_meter * some_meter; // outputs 100 m^2 std::cout << "some_mu_meter^2 = " << some_mu_meter * some_mu_meter; // outputs 1e+014 p(m^2)

Yet the square root operations is not compiled:

std::cout << "sqrt(some_meter) = " << sqrt(some_meter); // outputs 3.16228 m^(1/2) std::cout << "sqrt(some_mu_meter) = " << sqrt(some_mu_meter); //error here // 'value' : is not a member of 'boost::units::scale_dim_tag'

Also the following code fails to compile:

quantity<si::length, double> mu_meter(sqrt(1.0 * si::micro * si::meter * si::meter));

I used the following include files:

#include <iostream> #include <boost/units/quantity.hpp> #include <boost/units/make_scaled_unit.hpp> #include <boost/units/systems/si.hpp> #include <boost/units/cmath.hpp> #include <boost/units/io.hpp> #include <boost/units/scale.hpp> #include <boost/units/systems/si/prefixes.hpp>

### Attachments (0)

### Change History (9)

### comment:1 follow-up: 2 Changed 3 years ago by

### comment:2 Changed 3 years ago by

Replying to bnorman@…:

I'm hung up on exactly the same problem.

FYI, I am now able to work around this issue as follows:

typedef scaled_base_unit<si::meter_base_unit, scale<10, static_rational<-6> > >::type micro_meter_base_unit; typedef micro_meter_base_unit::unit_type micro_meter_unit;

### comment:3 Changed 3 years ago by

I'm stuck with the same problem. Is there any hope for a fix in the near future? It would really be greatly appreciated.

As far as I can see, the suggested work-around does not work in my case, since the scaled unit is not a base unit. In my application, I need a kilojoule unit. The obvious approach would be:

typedef make_scaled_unit<si::energy, scale<10, static_rational<3> > >::type energy_unit_kJ;

However, if this unit is involved in any nontrivial calculations involving sqrt or pow, it fails as described above.

The scaled_base_unit workaround suggested by bnorman does not work directly since joule is not a base unit. Instead, I attempted to define a base unit from scratch, and set up the conversion factory manually:

struct energy_base_unit_kJ: base_unit<energy_base_unit_kJ, energy_dimension, 1> {

static std::string name() {return "kilojoule";}

static std::string symbol() { return "kJ"; }

};

BOOST_UNITS_DEFINE_CONVERSION_FACTOR(

energy_base_unit_kJ, si::energy, double, 1/1000.0);

The problem is that I cannot define the reverse conversion factor because si::energy is not a base unit, and BOOST_UNITS_DEFINE_CONVERSION_FACTOR requires its first argument to be a base unit.

If there is some clever way to work around this, I would appreciate a pointer in the right direction - but under all circumstances, it would really be convenient if make_scaled_unit just worked.

### comment:4 Changed 3 years ago by

Hi all, here's a fix for this problem:

namespace boost { namespace mpl { template<> struct divides_impl<boost::units::scale_dim_tag,boost::units::detail::static_rational_tag> { template<class T0, class T1> struct apply { typedef boost::units::scale_list_dim< boost::units::scale< (T0::base), typename mpl::divides<typename T0::exponent, T1>::type > > type; }; }; } }

The main problem is that boost::mpl::divides does not work for a scale_list_dim and a static_rational. Power works because boost::mpl::times is implemented in boost/units/detail/unscale.hpp. (In fact, my fix is the copy of that code, replacing "times" with "divides".)

I'll try to add the fix to the library, but it's my first time on boost trac, so I don't know how long that'll take.

### comment:5 follow-up: 6 Changed 3 years ago by

Thanks! It would be greatly appreciated if you could submit this fix to Boost trunk.

### comment:6 Changed 3 years ago by

Replying to Wouter Boomsma <wb@…>:

Thanks! It would be greatly appreciated if you could submit this fix to Boost trunk.

I'll try, I hope I'll have time to look into submitting on the weekend.

### comment:8 Changed 8 months ago by

The bug persists. Patch by "petamas" fixes compilation problem. Thanks a lot!

### comment:9 Changed 3 weeks ago by

Resolution: | → fixed |
---|---|

Status: | new → closed |

Version: | Boost 1.55.0 → Boost Development Trunk |

**Note:**See TracTickets for help on using tickets.

I'm hung up on exactly the same problem.