# call_a_heron.pl
# サブルーチンのテスト(2)
                                                
@ax = (25, 35, 45) ;                       # 3辺の値の定義
require "mysub/heron_sub.pl" ;             # サブルーチンを呼ぶ
@bx = &heron_sub(@ax) ;                    # サブルーチンの結果を引き継ぐ
  
$cx = sprintf "%.2f", $bx[3] ;             # 小数第2位までの設定
  
print <<EOF
\n a = $ax[0], b = $ax[1], c = $ax[2] \n   # 3辺の値の表示
S = ( $bx[0] √ $bx[1] )$bx[2] \n         # 面積のルート表示
S = $cx                                   # 面積の小数表示
EOF
  

# heron_sub.pl
# ヘロンの計算をするサブルーチン
  
# Heron の公式を用いて面積の値を算出する(出力引数は4つ)
# 出力引数の最初の2つは m √n の部分のmとnの値
# 出力引数の3番目は「空白」または「 /4」という文字列
# 出力引数の4番目は 面積の実数値
  
sub heron_sub                         # サブルーチンの宣言
   {
    my($a, $b, $c) = @_ ;             # 3辺 a,b,c の値を引き継ぐ
  
  # s = (a+b+c)/2 の計算            
    $s = $a + $b + $c ;              
    $s2 = $s/2 ;
    
  # 3辺の和が偶数でない場合は、各値を2倍してビットを1立てる
    if ($s %= 2)                      
      {map $_ *= 2, ($s2, $a, $b, $c) ; $odd = 1}
  
  # s(s-a)(s-b)(s-c) の部分の計算
    $ss = $s2*($s2-$a)*($s2-$b)*($s2-$c) ;  
  
  # 引数の設定
    $sq = sqrt $ss ;                  # 実数値のセット
    $ps = "" ;                        # 偶数の場合は空白をセット
    if ($odd == 1)                    # 奇数の場合は /4 をセット
      {$sq /= 4 ; $ps = ' / 4'}            
  
  # ルートを整理するサブルーチンの呼び出し
    require "mysub/a_root_b.pl" ;
  
  # 最終的な戻し引数
    (&a_root_b($ss), $ps, $sq)      
   }
  
1 ;                                   # サブルーチンの終了


# heron.pl
# ヘロンの公式
  
# 入力方法の説明
  print "\n" ; print " *" x 17 ;
print <<EOF ;
\n 入 力 : a-b-c の形で3辺の値を入力
出 力 : m √n の形と少数の2通り
終 了 : Enter Key
EOF
  print " *" x 17 ; print "\n" ;
  
  while(1)
{
# 3辺の入力
  print "\n 入力(例 30-40-50):" ;
  $ax = <STDIN>;
  if ($ax eq "\n") {last}
  chomp $ax ;
  @abc = split /-/, $ax ;
  
# サブルーチンの呼び出し
  require "mysub/heron_sub.pl" ;
  @hx = &heron_sub(@abc) ;
  $dec = sprintf "%.2f", $hx[3] ;
  
# 結果の出力
print <<EOF ;
\n a = $a, b = $b, c = $c
\n S = $hx[0] √ $hx[1] $hx[2]
\n S = $dec
EOF
}
  print "\nおしまい。\(^o^)/\n"