>>322
p < 0 のとき(= 三角形を作れない場合)は浮動小数点数の特性に関係なく無限ループになる。
sqrt(p) と同様にNANを返すには、if (p < 0) return 0 / (p - p); を追加すれば良い。

p > 0 のときは無限ループにならないはず。以下が検証プログラム。
https://ideone.com/mzemEM

x = sqrt(p), y = p / x とすると、浮動小数点数の特性により x == y とならない場合は存在する。
このとき、xとyの仮数部を整数と見なした値(以降では「仮数整数」と呼ぶ)の差は1なので、
z = (x + y) / 2 はxとyのうち仮数整数が偶数の方に一致する。zを新たなxとして代入しyとzを
再計算すれば、今度はxの仮数整数が偶数なのでzはxに必ず一致し、>>321の収束判定条件が成立する。

具体例で見ると、p = 2 のときはxの仮数整数が奇数なので x != z となるが、zを新たなxとして代入し
再計算すれば x == z が成立する。桁上がりが起こる p = 3.9999999999999996 のときも、同様に
再計算で x == z が成立する。p = 3 のときはxの仮数整数が偶数なので x == z が成立し再計算は不要。