質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

Q&A

解決済

2回答

6543閲覧

三角形の面積のプログラム(外積をつかって)

mercurian-teto

総合スコア75

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

0グッド

0クリップ

投稿2017/06/07 12:34

外積計算をする3点の座標から三角形のの面積をもとめる

1/6 * | (ベクトルA×ベクトルB) 内積 ベクトルC |

プログラムを
作ってコンパイルしたのですが、エラーが出てきました。

fortran

1program triangleofarea 2 implicit none 3 integer, parameter :: nc = 3 !ベクトル成分の数 4 real(8) v1( nc ), v2( nc ), v3( nc ), gaiseki( nc ) !3つのベクトル 5 real(8) naiseki, S !三角形の面積公式の内積の計算と面積 6 7 read(*, *) v1( 1 ), v1( 2 ), v1( 3 ) !3つのベクトルの読み込み 8 read(*, *) v2( 1 ), v2( 2 ), v2( 3 ) 9 read(*, *) v3( 1 ), v3( 2 ), v3( 3 ) 10 11 call triangle_area( nc, v3, gaiseki, naiseki, S )!三角形の面積を計算する 12 !サブルーチンの呼び出し 13 write(*, *) S !結果の出力 14 15end program triangleofarea 16 17 subroutine triangle_area( vsize, v3, gaiseki, naiseki, S) 18 implicit none 19 integer, intent(in) :: gaiseki( vsize ) 20 integer, intent(in) :: v3 21 integer, intent(out) :: naiseki, S 22 integer i 23 24 call gaisekikeisann( vsize, v1, v2, gaiseki, S ) 25 26 naiseki = 0.0d0 !変数の初期化 27 28 do i = 1 , vsize 29 naiseki= naiseki + gaiseki( i ) * v3( i ) !内積の計算 30 enddo 31 S = 1 / 6 * abs( naiseki ) 32 33 end subroutine triangle_area 34 35 subroutine gaisekikeisann(vsize, vector1, vector2, gaiseki ) 36 37 implicit none 38 39 integer, intent(in) :: vsize 40 real(8), intent(in) :: vector1( vsize ), vector2( vsize ) 41 integer, intent(out) :: gaiseki( vsize ) 42 !gaiseki(外積)の計算 43 gaiseki( 1 ) = vector1( 2 ) * vector2( 3 ) - vector1( 3 ) * vector2( 2 ) 44 gaiseki( 2 ) = vector1( 3 ) * vector2( 1 ) - vector1( 1 ) * vector2( 3 ) 45 gaiseki( 3 ) = vector1( 1 ) * vector2( 2 ) - vector1( 2 ) * vector2( 1 ) 46 47 end subroutine gaisekikeisann

エラーは以下の通りです。

fortran

1 subroutine triangle_area( vsize, v3, gaiseki, naiseki, S) 2 1 3Error: Symbol 'vsize' at (1) has no IMPLICIT type 4triangleofarea_rep7.f90:24:34: 5 6 call gaisekikeisann( vsize, v1, v2, gaiseki, S ) 7 1 8Error: Symbol 'v1' at (1) has no IMPLICIT type 9triangleofarea_rep7.f90:24:38: 10 11 call gaisekikeisann( vsize, v1, v2, gaiseki, S ) 12 1 13Error: Symbol 'v2' at (1) has no IMPLICIT type 14triangleofarea_rep7.f90:17:38: 15 16 subroutine triangle_area( vsize, v3, gaiseki, naiseki, S) 17 1 18Error: PROCEDURE attribute conflicts with INTENT attribute in 'v3' at (1) 19triangleofarea.f90:11:21: 20 21 call triangle_area( nc, v3, gaiseki, naiseki, S )!三角形の面積を計算する 22 1 23Warning: Type mismatch in argument 'vsize' at (1); passed INTEGER(4) to UNKNOWN 24

どこが間違えているのか全く分かりません。
添削お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Fortran

1 subroutine triangle_area( vsize, v3, gaiseki, naiseki, S) 2 implicit none 3 integer, intent(in) :: gaiseki( vsize ) 4 integer, intent(in) :: v3 5 integer, intent(out) :: naiseki, S 6 integer i 7 8 call gaisekikeisann( vsize, v1, v2, gaiseki, S ) 9 10 naiseki = 0.0d0 !変数の初期化 11 12 do i = 1 , vsize 13 naiseki= naiseki + gaiseki( i ) * v3( i ) !内積の計算 14 enddo 15 S = 1 / 6 * abs( naiseki ) 16 17 end subroutine triangle_area

ここで使っているvsize変数は宣言されてませんよってimplicit noneに怒られているわけです。

引数で渡されたものはちゃんと宣言してください。

投稿2017/06/07 13:01

_Victorique__

総合スコア1392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_Victorique__

2017/06/07 19:03

よく分かんないマイナス付いてますね... テラテイルって何故マイナスがついたかを書かせるようにした方がいいと思うんだけど。
mercurian-teto

2017/06/08 09:54

添削ありがとうございます。 主プログラムの宣言がsubroutineにも影響するものだと誤解していました。 プログラムをなおしました。 ``` program triangleofarea implicit none integer, parameter :: nc = 3 !ベクトル成分の数 real(8) v1( nc ), v2( nc ), v3( nc ), gaiseki( nc ) !3つのベクトル real(8) naiseki, S !三角形の面積公式の内積の計算と面積 read(*, *) v1( 1 ), v1( 2 ), v1( 3 ) !3つのベクトルの読み込み read(*, *) v2( 1 ), v2( 2 ), v2( 3 ) read(*, *) v3( 1 ), v3( 2 ), v3( 3 ) call triangle_area( nc, v1, v2, v3, gaiseki, naiseki, S )!三角形の面積を計算する !サブルーチンの呼び出し write(*, *) S !結果の出力 end program triangleofarea subroutine triangle_area( vsize, vector1, vector2, vector3, gaiseki, naiseki, S) implicit none integer, intent(in) :: vsize real(8), intent(in) :: vector1( vsize ), vector2( vsize ), vector3( vsize ) real(8), intent(in) :: gaiseki( vsize ) real(8), intent(out) :: naiseki, S integer i call gaisekikeisann( vsize, vector1, vector2, gaiseki ) naiseki = 0.0d0 !変数の初期化 do i = 1 , vsize naiseki= naiseki + gaiseki( i ) * vector3( i ) !内積の計算 enddo S = 1 / 6 * abs( naiseki ) end subroutine triangle_area subroutine gaisekikeisann( vsize, vector1, vector2, gaiseki ) implicit none integer, intent(in) :: vsize real(8), intent(in) :: vector1( vsize ), vector2( vsize ) real(8), intent(out) :: gaiseki( vsize ) !gaiseki(外積)の計算 gaiseki( 1 ) = vector1( 2 ) * vector2( 3 ) - vector1( 3 ) * vector2( 2 ) gaiseki( 2 ) = vector1( 3 ) * vector2( 1 ) - vector1( 1 ) * vector2( 3 ) gaiseki( 3 ) = vector1( 1 ) * vector2( 2 ) - vector1( 2 ) * vector2( 1 ) end subroutine gaisekikeisann ```
_Victorique__

2017/06/08 10:02

エラーは改善されましたか?
mercurian-teto

2017/06/08 10:18

上の改善したものにさらに改善を加えたのが一番下に書いてあるプログラムです。 いちよう、コンパイルが通ったのですが、 答えが何を入れても0になってしまいます。 答えが0になるのは宣言文で最終亭な計算結果を表す変数をintegerの整数にしたとき しか考えられないと思うのですが、 最終的な答えであるSはreal(8)になっていますし、 答えが0になってしまう理由がわかりません。 なぜ、何を入れても答えが0になるのでしょうか。 ``` program triangleofarea implicit none integer, parameter :: nc = 3 !ベクトル成分の数 real(8) v1( nc ), v2( nc ), v3( nc ), gaiseki( nc ) !3つのベクトル real(8) naiseki, S !三角形の面積公式の内積の計算と面積 read(*, *) v1( 1 ), v1( 2 ), v1( 3 ) !3つのベクトルの読み込み read(*, *) v2( 1 ), v2( 2 ), v2( 3 ) read(*, *) v3( 1 ), v3( 2 ), v3( 3 ) call triangle_area( nc, v1, v2, v3, gaiseki, naiseki, S )!三角形の面積を計算する !サブルーチンの呼び出し write(*, *) S !結果の出力 end program triangleofarea subroutine triangle_area( vsize, vector1, vector2, vector3, gaiseki, naiseki, S) implicit none integer, intent(in) :: vsize real(8), intent(in) :: vector1( vsize ), vector2( vsize ), vector3( vsize ) real(8), intent(out) :: gaiseki( vsize ) real(8), intent(out) :: naiseki, S integer i call gaisekikeisann( vsize, vector1, vector2, gaiseki ) naiseki = 0.0d0 !変数の初期化 do i = 1 , vsize naiseki= naiseki + gaiseki( i ) * vector3( i ) !内積の計算 enddo S = 1 / 6 * abs( naiseki ) end subroutine triangle_area subroutine gaisekikeisann( vsize, vector1, vector2, gaiseki ) implicit none integer, intent(in) :: vsize real(8), intent(in) :: vector1( vsize ), vector2( vsize ) real(8), intent(out) :: gaiseki( vsize ) !gaiseki(外積)の計算 gaiseki( 1 ) = vector1( 2 ) * vector2( 3 ) - vector1( 3 ) * vector2( 2 ) gaiseki( 2 ) = vector1( 3 ) * vector2( 1 ) - vector1( 1 ) * vector2( 3 ) gaiseki( 3 ) = vector1( 1 ) * vector2( 2 ) - vector1( 2 ) * vector2( 1 ) end subroutine gaisekikeisann ```
_Victorique__

2017/06/08 10:34

そこはデバッグの域なので、write文を駆使してどこで値がおかしくなっているのか確かめてください。それでも分からないような内容なら、デバッグの詳細と共にコメントください。
mercurian-teto

2017/06/08 11:17

write文を駆使するというのことはwrite文の表示方法を変えるということですか、 いちよう write(*,'(f15.10)') S にかえてみたのですが、 変化がありませんでした。
_Victorique__

2017/06/08 12:20

プログラムの処理ごとに各変数を出力して、計算結果があっているかをwrite文を入れて逐一確かめてください、という意味です。
mercurian-teto

2017/06/08 14:16

まず最初に1 / 6が倍精度実数でないので1.0d0 / 6.0d0に替えました。 変化がありませんでした。 次にnaisekiのところにwrite文を入れました。 ``` write(*, *) naiseki ```` しかし、これもまた何も変化がありませんでした。 つぎに新たに加えたwrite文をけして、適当に横に改行したりして?実行したら、 なぜかちゃんと答えが求まるようになりました。 どこか横に改行したの?、1/6のところを倍精度実数に変換したのでたぶんできるようになりました。 このteratailでは横への改行が判定されていないので結局よくわからないまま 計算ができるようになってしまいました。 添削ありがとうございました。 ``` program triangleofarea implicit none integer, parameter :: nc = 3 !ベクトル成分の数 real(8) v1( nc ), v2( nc ), v3( nc ), gaiseki( nc ) !3つのベクトル real(8) naiseki, S !三角形の面積公式の内積の計算と面積 read(*, *) v1( 1 ), v1( 2 ), v1( 3 ) !3つのベクトルの読み込み read(*, *) v2( 1 ), v2( 2 ), v2( 3 ) read(*, *) v3( 1 ), v3( 2 ), v3( 3 ) call triangle_area( nc, v1, v2, v3, gaiseki, naiseki, S )!三角形の面積を計算する !サブルーチンの呼び出し write(*,*) S !結果の出力 end program triangleofarea subroutine triangle_area( vsize, vector1, vector2, vector3, gaiseki, naiseki, S) implicit none integer, intent(in) :: vsize real(8), intent(in) :: vector1( vsize ), vector2( vsize ), vector3( vsize ) real(8), intent(out) :: gaiseki( vsize ) real(8), intent(out) :: naiseki, S integer i call gaisekikeisann( vsize, vector1, vector2, gaiseki ) naiseki = 0.0d0 !変数の初期化 do i = 1 , vsize naiseki= naiseki + gaiseki( i ) * vector3( i ) !内積の計算 enddo S = 1.0d0 / 6.0d0 * abs( naiseki ) end subroutine triangle_area subroutine gaisekikeisann( vsize, vector1, vector2, gaiseki ) implicit none integer, intent(in) :: vsize real(8), intent(in) :: vector1( vsize ), vector2( vsize ) real(8), intent(out) :: gaiseki( vsize ) !gaiseki(外積)の計算 gaiseki( 1 ) = vector1( 2 ) * vector2( 3 ) - vector1( 3 ) * vector2( 2 ) gaiseki( 2 ) = vector1( 3 ) * vector2( 1 ) - vector1( 1 ) * vector2( 3 ) gaiseki( 3 ) = vector1( 1 ) * vector2( 2 ) - vector1( 2 ) * vector2( 1 ) end subroutine gaisekikeisann ```
_Victorique__

2017/06/08 14:20

改善されたみたいで良かったです! デバッグの方法も今後に活かしてみてください。
guest

0

サブルーチンの引数にも型宣言が必要です。

v3が2箇所で宣言されています。

投稿2017/06/07 12:49

seastar3

総合スコア2285

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問