+
+/* Compute square root. */
+
+profile_probability
+profile_probability::sqrt () const
+{
+ if (!initialized_p () || *this == never () || *this == always ())
+ return *this;
+ profile_probability ret = *this;
+ ret.m_quality = MIN (ret.m_quality, ADJUSTED);
+ uint32_t min_range = m_val;
+ uint32_t max_range = max_probability;
+ if (!m_val)
+ max_range = 0;
+ if (m_val == max_probability)
+ min_range = max_probability;
+ while (min_range != max_range)
+ {
+ uint32_t val = (min_range + max_range) / 2;
+ uint32_t val2 = RDIV ((uint64_t)val * val, max_probability);
+ if (val2 == m_val)
+ min_range = max_range = m_val;
+ else if (val2 > m_val)
+ max_range = val - 1;
+ else if (val2 < m_val)
+ min_range = val + 1;
+ }
+ ret.m_val = min_range;
+ return ret;
+}
+
+/* Compute n-th power of THIS. */
+
+profile_probability
+profile_probability::pow (int n) const
+{
+ if (n == 1 || !initialized_p ())
+ return *this;
+ if (!n)
+ return profile_probability::always ();
+ if (!nonzero_p ()
+ || !(profile_probability::always () - *this).nonzero_p ())
+ return *this;
+ profile_probability ret = profile_probability::always ();
+ profile_probability v = *this;
+ int p = 1;
+ while (true)
+ {
+ if (n & p)
+ ret = ret * v;
+ p <<= 1;
+ if (p > n)
+ break;
+ v = v * v;
+ }
+ return ret;
+}