• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:perl 積算の仕方が解らない)

Perlで積算の仕方がわからない

このQ&Aのポイント
  • フォートランで作られたデータをperlで作り直そうとしています。perlの中で値の計算まではできましたが、2番目のフィールドの積算方法がわかりません。
  • awkでの積算方法は`awk '{SUM += $2;printf("%s %10.4e", $1, SUM)}'`ですが、perlではどのようにすれば良いのでしょうか?
  • また、awkとperlの計算結果は同じですが、フォートランの結果は微妙に異なっています。なぜでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

#2補足について。 この内容だと、Fortranでは単精度で処理されています。 参照: http://www.nag-j.co.jp/fortran/FI_17.html#AUTOTOC_17_3 実装にもよりますが、Cで言えば、float相当です。 http://ja.wikipedia.org/wiki/%E5%8D%98%E7%B2%BE%E5%BA%A6 にあるように、有効桁は、10進で7桁程度です。 Perlの内部ではCで言えば、double相当の精度で計算しています。 http://ja.wikipedia.org/wiki/%E5%80%8D%E7%B2%BE%E5%BA%A6 にあるように、有効桁は、10進で15桁程度です。 違いが出ているのは、7桁目です。 これは、単精度にとっては精度ぎりぎりの桁なので、誤差が出る箇所です。 対し、倍精度にとっては、まだ余裕のある桁です。 この差が、集計結果の違いに出ているのだと思われます。

nnirosan
質問者

お礼

FortranとPerlの計算結果の精度についての、詳しい説明 ありがとうございました。なんとか、自力でperlで積算を求めるスクリプトを書く事ができました。 有難うございました。

nnirosan
質問者

補足

詳細な説明有難うございました。 より良い知識を得る事が出来き、フォートランとperlの違いが少し解りました。 安心してperlへ切り替えたいと思います。 では、御存じでしたら、示しましたデータについて、2フィールド目の指数表示のデータについて、perlで積算データを出力させるスクリプトを、ご教授して頂けると大変助かります。 宜しくお願い致します。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

既に答えは書かれています. 全ての回答を見てください.

nnirosan
質問者

お礼

なんとか、自力でperlで積算を求めるスクリプトを書く事ができました。 有難うございました。

nnirosan
質問者

補足

osamuyさんにご教授頂いていたのですが、コマンドプロンプトの画面の図が、私のPC上では、昨日チラッと見えただけて、見えなくなってしまいました。 確か、1ライナーで書かれていたとおもいます。 出来れば、perlのスクリプトの中で while文を使い入力データを1行ずつ呼び出しては、積算させて、出力ファイルへ書かせたいのです。  説明不足も申し訳有りません。

全文を見る
すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

Fortranでは、どの型を使っていますか? Perlでは、内部で倍精度実数相当の計算をしています。 Fortranで単精度を使っているなら、精度の違いが出ます。

nnirosan
質問者

お礼

FortranとPerlの計算結果の精度についての、詳しい説明 ありがとうございました。なんとか、自力でperlで積算を求めるスクリプトを書く事ができました。 有難うございました。

nnirosan
質問者

補足

フォートランスクリプトの中身を下記に記述しました。 お恥ずかしい事に、私にはさっぱりわかりません。 ene=でエネルギーの計算をして enecum=でエネルギーの積算を作っているようです。 open(11,file='lfall.dat') open(12,file='enecum.dat') open(13,file='eneind.dat') read (11,'(2(1x,i4,4i2),2x,a3)') iyrf1,monf1,idyf1,ihrf1, & minf1,iyrf2,monf2,idyf2,ihrf2,minf2,stnm ! period,station read (11,'(2(1x,i4,4i2))') iyrd1,mond1,idyd1,ihrd1, & mind1,iyrd2,mond2,idyd2,ihrd2,mind2 ! data read (11,'(1x,3i6)') iymax,itickdy ! Ymax,Ytick-int read (11,'(1x,3i6)') iamaxmm,iamaxnmps,idur ! legend Amax, dt write(*,'(2(1x,i4,4i2))') iyrf1,monf1,idyf1,ihrf1,minf1, & iyrf2,monf2,idyf2,ihrf2,minf2 write(*,'(2(1x,i4,4i2))') iyrd1,mond1,idyd1,ihrd1,mind1, & iyrd2,mond2,idyd2,ihrd2,mind2 write(*,'(1x,2i6)') iymax,itickdy write(*,'(1x,3i6)') iamaxmm,iamaxnmps,idur ! iamaxmm is fix read(11,'(1x)') c enecum=0.0 pi=3.1415 rho=2600.0 c=3500.0 r0=20000.0 r02=r0**2 fact=0.00000001 fk=0.5 c 1 continue read(11,1102) IY00,IM00,ID00,IH100,IMI100,IH200,IMI200, 1 LDMIN, ampx 1102 format(1x,i4,2i2,1x,2i2,1x,2i2,i5,f7.1) if(IY00 .gt. 2020 .or. IY00 .lt. 1) go to 9000 ampxm=0.5*ampx*fact ene=2.0*fk*pi*60.0*float(LDMIN)*rho*c*r02*ampxm**2 write(13,1210) oy,ene enecum=enecum+ene call time1(IY00,IM00,ID00,IH100,IMI100,oy) write(12,1200) oy,enecum write(*,1202) oy,enecum,ampx,ampxm,ene 1200 format(f10.4,3x,e12.5) 1210 format(f10.4,3X,e15.8) 1202 format(f10.4,3x,4e12.5) go to 1 9000 continue stop end subroutine time1(iy,im,id,ih,imin,oy) dimension imday(12) imday(1)=0 imday(2)=31 imday(3)=59 imday(4)=90 imday(5)=120 imday(6)=151 imday(7)=181 imday(8)=212 imday(9)=243 imday(10)=273 imday(11)=304 imday(12)=334 c f4=0.0 m4y=mod(iy,4) if(m4y .eq. 0) then f4=1.0 if(iy .eq. 2000) f4=0.0 if(im .gt.2) f40=f4 endif if40=f40 fd=(float(ih)+float(imin)/60.0)/24.0 fd=fd+float(id) fm=float(imday(im)+if40)+fd fm=fm/(365.0+f4) oy=float(iy)+fm return end

全文を見る
すると、全ての回答が全文表示されます。
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

一例。 >awkとperlの計算結果は全く同じにでましたが、フォートランの結果は下記のように微妙に違ってしまう処がございます。 いわば環境依存です。 awkやperlは、OS標準ライブラリを使ってデータを読み込んだり、値を処理しているので。 計算誤差とかは別途検討する必要があります。

nnirosan
質問者

お礼

1ライナーperlでの積算方法有難うございました。 記憶に留めさせて頂きます。 補足に、自力で作ったperlのスクリプトを記述させて頂きました、まったくのperlの初心者でお恥ずかしいかぎりです。

nnirosan
質問者

補足

#! /usr/bin/perl open ( InFile, "< /home/tanaka/lfall.dat"); open ( OutFile, "> /home/tanaka/ene-perl.dat" ); open ( OutFileseki, "> /home/tanaka/lfall.dat.out" ); while ( <InFile> ) { chop; s/ +/ /g; s/^ //; s/\t/ /g; @Data = split ( / /, $_ ); $Nf = @Data; if ( $Nf == 5 ) { ( $DateA , $DateB , $DateC , $min , $kando ) = split ( / /, $_ ); if ( $DateA != '00000000' ) { $countWC+= '1'; #print " 444 $DateA , $DateB , $DateC , $min , $kando 555\n"; $en = (2 * 0.5 * 3.1415 * 60 * $min * 2600 * 3500 * 20000 * 20000 * (0.5 * $kando * 0.00000001) * (0.5*$kando * 0.00000001)); #print "444 $en\n"; $YYYY = substr($DateA,0,4); $MM1 = substr($DateA,4,2); $DD = substr($DateA,6,2); $HH = substr($DateB,0,2); $MM = substr($DateB,2,2); $Time = "${YYYY}-${MM1}-${DD}T${HH}:$MM"; $EN = sprintf ( "%10.5E", $en); ###printf OutFile ( "%s %s\n", $Time, $EN ); ( $EN1, $EN2) = split ( /\+/, $EN); ($En1, $En2) = split ( /\./, $EN1 ); $EN3 = $EN2 + 1; $AA = '0.'; $BB = '+'; printf OutFile ( "%s %s%s%s%s%02d\n", $Time, $AA, $En1, $En2, $BB, $EN3 ); if ( $countWC == '1' ) { printf OutFileseki ( "%s %s%s%s%s%02d %s\n", $Time, $AA, $En1, $En2, $BB, $EN3, $countWC ); $enecum += $en; }else{ $enecum += $en; $enecum1 = sprintf ("%10.5E", $enecum); ($ENcum1, $ENcum2) = split ( /\+/, $enecum1); ($Encum1, $Encum2) = split ( /\./, $ENcum1 ); $ENcum3 = $ENcum2 + 1; printf OutFileseki ( "%s %s%s%s%s%02d %s\n", $Time, $AA, $Encum1, $Encum2, $BB, $ENcum3, $countWC ); } } } } close ( InFile ); close ( OutFile ); close ( OutFileseki );

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 整数の指数を少数の指数で表示したい

    awkで計算をさせた結果、下記のような値になりますが、 echo "" | awk '{ OFMT = "%5e"} {print 2*0.5*3.1415*60*8*2600*3500*20000*20000*(0.5*64.6*0.00000001)*(0.5*64.6*0.00000001) }' =  5.726440e+05 この5.726440e+05--> 0.5726440e+06 と出したいのですが方法が解りません。 awkでも、perlでも良いので、このような表示にする方法を教えてください。

    • ベストアンサー
    • Perl
  • 16進数のデータをソートするには?

    Linux上で16進数のデータをソートしたいのですがどうすれば実現できるでしょうか? [test.txt] 11009 292f 6551 e6f6 ↓のようにソートしたい 292f 6551 e6f6 11009 手順はまず、16進数→10進数に変換してからソートでしょうか? もしそうだとしても10進数に変換するところでつまずいています。 awkのprintfでやると下記のようにエラーがでます。 (頭に0xを追加して試してもダメでした) $ awk '{printf (%d, $1)}' test.txt awk: {printf (%d, $1)} awk: ^ syntax error awk: {printf (%d, $1)} awk: ^ syntax error ↓これだと変換できるのは知っているのですが・・・。 $ printf "%d\n" 0x292f 10543 以上、よろしくお願いします。

  • awkの使い方について教えてください。

    awkとperlなどの初心者です。 使い方が分かっていないのですが、 例えば出力のフィールドセパレータを,に変更するには どうすればいいでしょうか? awk '{OFS=,;print}' fileなどとやってみますが、 うまくいきません。2つ以上のコマンドを実行するときの 文法がわかっていないような気がするのですが。 あとperlでよくみかけるperl -neのnは何でしょうか? man perlとやってみても-wと-eの意味しかのっていなくて なからないのですが。ご教授下さい。

  • データのカウント方法について(C言語初心者です)

     二次元配列(10×10)の中のある特定のデータx[i][j][1]の総数を出力するというプログラムを作っています。  しかし、これだとデータがうまくカウントされません。x[i][j][1]は他の関数内で計算するようにしています。 int t, sum=0; for(t=0;t<=1000;t++){ for(i=0;i<N;i++){ for(j=0;j<N;j++){ sum=sum+x[i][j][1];      } } } printf("%d ?n", sum);  何が悪いのでしょうか?教えて頂けたら幸いです。

  • 3行ずつ足す

    AWK を使っていあのですが、perl への移行を目指して勉強しています。 (1) 行数が3の倍数 (2) 列数は分からない(スペース区切り。固定列数) (3) # はコメント行 というデータがあります。 このデータを perl に読み込ませて、  三行ずつ足して出力する ようなプログラムをつくっています。 例えば、6行4列のデータ test.dat # comment 1 2 3 5 3 2 1 6 2 2 2 7 4 5 6 7 6 5 4 6 5 5 5 5 を cat test.dat | sum3row.pl のように perl のプログラム sum3row.pl に読みこませて、三行ずつ足して # comment 6 6 6 18 18 18 18 18 という出力を得たいのです。 次の点で困ってます。 ●AWK の場合、今読み込んでいる行の列数は NF という変数で分かるのですが、perl ではよく分かりません。データへのアクセス自体は $data[2] のようにすれば良いことは分かっているのですが・・。 ●AWK の場合、今読み込んでいる行の番号は NR という変数で分かるのですが、perl ではよく分かりません。 すみませんが、よろしくお願いします。。 サンプルプログラムでも助かります(読んで自分で勉強しますので)。

    • ベストアンサー
    • Perl
  • 計算式の意味について(Perl)

    とあるソースを解析しているのですが、 Perlを初めてまだ日が浅いので 下記の計算式の最後の(1./60.)の意味がよくわかりません。 なぜ数字の後にドットが入っているのでしょうか? どなたかご教示お願いいたします。 $d = ($t - $dly - $t0) - ($c - $c0)*(1./60.);

    • ベストアンサー
    • Perl
  • JavaScriptの計算結果をPerlに取込みたいが

    Perlで作成したCGIの中で、JavaScriptのファンクションを使っていますが、この計算結果をPerlに取込みたいのですが、うまくできません。基本がわかっていないので、よろしくご教授お願いします。

    • ベストアンサー
    • Perl
  • perl 文字列検索後に指定フィールドの値を変数へ

    菊池と申します。 perlスクリプトで下記のような文字列を検索し、検索されたら指定したフィールドの値を変数に入れたいのですが、grepやawkを使うと、ファイル中のすべてが検索対象になってしまい困っております。 文字列検索の表現方法をご教授頂けると大変助かります。 下記へperlスクリプトの一部を記載させて頂きました、データはcsv形式です。 変数に入れる事が出来なかったので、抽出した値をファイルへ出力させています。 検索文字列=2013/11/19,09:00:00,13:00:00 データの中味 <94>N/<8c><8e>/<93>ú,<89>ð<90>Í<8a>J<8e>n<8e><9e><8d><8f>,<89>ð<90>Í<8f>I<97>¹<8e><9e><8d><8f>,<8c>ö<8b>¤<8d>À<95>WX(m),<8c>ö<8b>¤<8d>À<95>WY(m),<95>W<8d><82>H(m),<88>Ú<93>®<95>½<8b>Ï<92>lX(m),<88>Ú<93>®<95>½<8b>Ï<92>lY(m),<88>Ú<93>®<95>½<8b>Ï<92>lH(m),<8f><89><8a>ú<92>l<82>©<82>ç<82>Ì<95>Ï<93>®<97>ÊX(m),<8f><89><8a>ú<92>l<82>©<82>ç<82>Ì<95>Ï<93>®<97>ÊY(m),<8f><89><8a>ú<92>l<82>©<82>ç<82>Ì<95>Ï<93>®<97>ÊH(m),2D<8b><97><97>£(m),3D<8b><97><97>£(m),<88>Ú<93>®<95>½<8b>Ï2D<8b><97><97>£(m),<88>Ú<93>®<95>½<8b>Ï3D<8b><97><97>£(m),<91>ª<88>Ê<83>t<83><89><83>O,<91>ª<88>Ê<90>¸<93>x,<88>Ù<8f>í<92>l<83>t<83><89><83>O<81>i<8f><89><8a>ú<92>l<81>j,<88>Ù<8f>í<92>l<81>i<8c>x<89>ú<83><89><83><93><83>N<81>j,<94>ò<82>Ñ<92>l<83>t<83><89><83>O, 2013/11/18,01:00:00,05:00:00,-68213.2327,17746.2653,2093.7982,-9999.0000,-9999.0000,-9999.0000,5.0099,-0.5989,-4.8100,16215.1100,16255.8006,-9999.0000,-9999.0000,4,0.0019,0,0,0, 2013/11/18,05:00:00,09:00:00,-68213.2273,17746.2666,2093.7872,-9999.0000,-9999.0000,-9999.0000,5.0153,-0.5976,-4.8210,16215.1061,16255.7959,-9999.0000,-9999.0000,4,0.0014,0,0,0, 2013/11/18,09:00:00,13:00:00,-68213.2256,17746.2692,2093.7792,-9999.0000,-9999.0000,-9999.0000,5.0170,-0.5950,-4.8290,16215.1030,16255.7923,-9999.0000,-9999.0000,4,0.0016,0,0,0, 2013/11/18,13:00:00,17:00:00,-68213.2236,17746.2737,2093.7682,-9999.0000,-9999.0000,-9999.0000,5.0190,-0.5905,-4.8400,16215.0981,16255.7866,-9999.0000,-9999.0000,4,0.0014,0,0,0, 2013/11/18,17:00:00,21:00:00,-68213.2306,17746.2741,2093.7672,-9999.0000,-9999.0000,-9999.0000,5.0120,-0.5901,-4.8410,16215.1015,16255.7899,-9999.0000,-9999.0000,4,0.0016,0,0,0, 2013/11/18,21:00:00,01:00:00,-68213.2308,17746.2739,2093.7882,-9999.0000,-9999.0000,-9999.0000,5.0118,-0.5903,-4.8200,16215.1017,16255.7916,-9999.0000,-9999.0000,4,0.0016,0,0,0, 2013/11/19,01:00:00,05:00:00,-68213.2221,17746.2743,2093.8062,-9999.0000,-9999.0000,-9999.0000,5.0205,-0.5899,-4.8020,16215.0968,16255.7880,-9999.0000,-9999.0000,4,0.0017,0,0,0, 2013/11/19,05:00:00,09:00:00,-68213.2140,17746.2808,2093.7982,-9999.0000,-9999.0000,-9999.0000,5.0286,-0.5834,-4.8100,16215.0870,16255.7777,-9999.0000,-9999.0000,4,0.0013,0,0,0, 2013/11/19,09:00:00,13:00:00,-68218.2472,17746.8587,2098.6543,-9999.0000,-9999.0000,-9999.0000,-0.0046,-0.0055,0.0461,16217.2238,16258.2532,-9999.0000,-9999.0000,4,0.0017,0,0,1, 2013/11/19,13:00:00,17:00:00,-68218.2538,17746.8600,2098.6633,-9999.0000,-9999.0000,-9999.0000,-0.0112,-0.0042,0.0551,16217.2263,16258.2563,-9999.0000,-9999.0000,4,0.0014,0,0,1, 2013/11/19,17:00:00,21:00:00,-68218.2603,17746.8538,2098.6473,-9999.0000,-9999.0000,-9999.0000,-0.0177,-0.0104,0.0391,16217.2349,16258.2638,-9999.0000,-9999.0000,4,0.0016,0,0,1,   <<スクリプトの一部>> #`grep "'2013/11/19,09:00:00,13:00:00'" $SS | awk -F"," '{print \$13}' $SS > $SS-2D`; #`grep "'2013/11/19,09:00:00,13:00:00'" $SS | awk -F"," '{print \$14}' $SS > $SS-3D`; `awk -F"," '\$1 ~ \/2013\/11\/19\/ && \$2 == \/09\:00\:00\/ {print \$13}' $SS > $SS-2D`; `awk -F"," '\$1 ~ \/2013\/11\/19\/ && \$2 == \/09\:00\:00\/ {print \$14}' $SS > $SS-3D`; 以上 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Firefoxでのperl解釈

    根本的な理解不足か悩んでおります。 CSSの表示チェックのため最近FirefoxとIEでサイトを確認するようになりました。 windowsXPproのsp2でIE6ではperlで作った自作スクリプトが思ったように表示されますが、Firefox2では意図したとおり表示されません。 javascriptが混じっている場合javascriptの解釈の違いでうまくいかないことがあることは理解しているつもりです。 今回のperlによる自作スクリプトにはjavascriptは含まれません。perlのみです。 perlはウェブのサーバーで実行されて結果のHTMLを返すと思っていましたが、違うのでしょうか? 教えたいただきたいことはperlやphpで作成したスクリプト(javascriptなどを含まないもの)の結果がブラウザにより違うことがあるのかどうかです。 よろしくお願いします。 参考までに上記のperlスクリプトの一部です。 変数設定など終わり最終のhtml振り分けです。 &checked; exit; 計算結果により飛び先が変わります。 sub checked{ if ($sum < 2){&resalt1;} if ($sum < 6){&resalt2;} if ($sum < 12){&resalt3;} if ($sum < 16){&resalt4;} } sub resalt1{ print <<"EOM"; <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <META HTTP-EQUIV="Refresh" CONTENT="0;URL=http://www.asaka-d.com/shindan/shindan1.html"> </head><body> </body></html> EOM } 以下 resalt2、3、4とありURLが変わっているだけです。 IEの場合とび先のサブルーチンのURLを表示し終了しますが、Firefoxの場合はsub checkdに戻り最後の判定まで行き必ずresalt4のURLに飛んでいきます。 スクリプトのつくりが甘かったのは事実です。かくresaltサブルーチンの最後にexit;を加えることで解決しました。 でもCGIの結果がブラウザにより変わるとは思えません。よろしくご指導ください。

  • CからPerlへの変換がうまくいきません

    Cで作った二項分布の計算プログラムをPerlで書き直しています。 ユーザ関数の使い方がよくわかりません。 どこが間違っているか教えていただけませんでしょうか? 余談ですが、ソースが左揃えになるのを防ぎたいのですが…。 #!/usr/bin/perl $p = 0.5, $s = 0, $t = 0, $combination = 0, $binarydistribution = 0; printf("n="); $n = <STDIN>; for ($r = 0; $r <= $n; $r++){ $combination = &factorial($n) / (&factorial($r) * &factorial($n - $r)); $s = 1; for ($i = 1; $i <= $r; $i++){ $s = $s * $p; } $t = 1; for ($i = 1; $i <= $n - $r; $i++){ $t *= (1 - $p); } $binarydistribution = $combination * $s * $t; printf("%.15f\n", $binarydistribution); } sub factorial{ $j = @_; $x = 1; for ($i = 1; $i <= $j; $i++){ $x *= $i; } return $x; }

    • ベストアンサー
    • Perl