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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

2回答

673閲覧

再帰文においての1/2の扱いに疑問

Eston

総合スコア67

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2018/12/13 00:07

編集2018/12/13 08:07

いつもお世話になっております。

現在、再帰文を学習しているのですが、少し理解に戸惑う出力結果が出たので、質問いたします。

下記のコードの出力結果ですが、

14
7
21
21
7
21

となります。

メインの疑問点
1)funは再帰関数になっているのか?
2)4つ目の出力がなぜ21になるのかが疑問です。
それ以外の出力は、例として出しました。

また、再帰文についての理解を深めたいので、その他にもご指摘いただける部分があれば、お願いいたします。

私の考えでは、1/2は0余り1なので、一番最後のreturnの処理に入ると考えていますが、どうでしょうか?

*(a+aつまりa+a=7+7=14、そして更に()の外の+aを足して、21が出力されると考えているのですが、なぜ()の外で+aを行えば、aにaが加算されるのか説明ができませんし、その考えは、出力により誤りだと証明されているので、違う考え方で、どう動いているのか知りたいです。)

そもそも、メッソドを呼び出した時には、何が出力されているのでしょうか?
私の理解では、この再帰文のなかでは、bが回数制限(for文のi<lengthのような使い方)をされていて、出力されているのは、aの値だと思っていたのですが、やはり間違っていますでしょうか?

Java

1 2public class teratailToAsk { 3 4 public static void main(String[] args) { 5 // TODO 自動生成されたメソッド・スタブ 6 System.out.println(fun(7, 2)); 7 System.out.println(fun(7, 1)); 8 System.out.println(fun(7, 3)); 9 System.out.println(fun2(7, 2)); 10 System.out.println(fun2(7, 1)); 11 System.out.println(fun2(7, 3)); 12 13 } 14 public static int fun(int a, int b) 15 { 16 if (b == 0) 17 return 0; 18 if (b % 2 == 0) 19 return fun2(a+a, b/2); 20 //else 21 return fun2(a+a, b/2) + a; 22 } 23 24 public static int fun2(int a, int b) 25 { 26 if (b == 0) 27 return 0; 28 if (b%2==0) 29 return fun2(a+a, b/2) + a; 30 31 return fun2(a+a, b/2) + a; 32 } 33 34} 35

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

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

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

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

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

maisumakun

2018/12/13 00:29

もう少し疑問を明確にしてください。「1/2は0余り1なので、一番最後のreturnの処理に入る」のがfunの話なのかfun2の話なのかすらわかりません。
guest

回答2

0

出てきた数字、疑問点から、4つ目の

System.out.println(fun2(7, 2));

のことだと判断して回答してみます。違ったら指摘してください。

fun2のbの条件分岐が全く機能していないようですが、コード通りにたどると

plain

1 fun2(7, 2) = fun2(7+7, 2/2) + 7 2 fun2(14, 1) = fun(14+14, 1/2) + 14 3 fun(28, 0) = 0 4 ∴fun2(14, 1) = 0 + 14 = 14 5∴fun2(7, 2) = 14 + 7 = 21 6-> 21が返され、出力される

投稿2018/12/13 01:38

swordone

総合スコア20649

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

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

0

ベストアンサー

まずfunは再帰関数ではありません
その中でfun()を実行しないからです
fun2はその中でfun2()を実行するので再帰関数です

もしfun()がその中で呼び出しているのが
fun2()ではなくfun()なら
fun(a,b)は再帰関数となり
任意の整数a,bの積を計算する関数となります

Java

1public class sample { 2 public static void main(String[] args) { 3 System.out.println(multi(5,9));//単純な例 4 System.out.println(multi(1,1431655594));//深い再帰の例 5 } 6 7 public static int multi(int a, int b) 8 { 9 if (b == 0){ 10 System.out.println("b="+b+" b==0");//どのif文を実行しているか確認用 11 return 0; 12 }else if (b%2 == 0){ 13 System.out.println("b="+b+" b%2==0");//どのif文を実行しているか確認用 14 return multi(a+a, b/2);//ここで自分自身を実行している 15 }else{ 16 System.out.println("b="+b+" b%2!=0");//どのif文を実行しているか確認用 17 return multi(a+a, b/2) + a;//ここで自分自身を実行している 18 } 19 } 20}

またfun2の2つ目のif文
if (b%2==0)
は意味がありません
ifに入ろうが入るまいが
returnで返される値はいずれも
fun2(a+a, b/2) + a
だからです

b/2の値はfunおよびfun2の引数bがint型のため
切り捨てられて0が入ることになります

引数bがfloat型の場合は
bに「奇数/2」の値が入るとおかしな動作になると思います
%演算子は必ずしも整数のあまりを返しません
5.5%2 の場合は 1.5を返し
0.5%2 の場合は 0.5と言った具合に少数の値を返します

余談ですが
a+aをa2と解釈すると
hoge(a+a, b/2)は
hoge(a
2, b/2)となり
hoge(a<<1, b>>1) と
シフト演算を使って表す事ができます

Javaの仮想マシンやそれを実行するCPUは
おそらく乗算専用の命令やシステムを持っているでしょうから
意味はなく、むしろ遅くなってしまい
この再帰処理に
「再帰処理の学習に用いる以外の意味」は感じられません

ただ乗算処理装置を持たないCPU等を
機械語レベルで制御する場合に
これを使用する際には意味を持ちます
そのような場合に用いられる(もしくは用いられた)
再帰処理なのかもしれません
そこらへんに疎いのであくまで推測ですが

投稿2018/12/13 05:18

e-cube

総合スコア284

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

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

swordone

2018/12/13 19:24

そもそもintを要求しているところにfloatを渡せないと思うんだが
e-cube

2018/12/14 01:22

もちろんそうです しかしご存知のように floatを要求しているところにintは渡すことができてしまいます したがって multi(整数,整数)で使用した場合は multi(int a, int b)でも multi(int a, float b)でも 動作はします この再帰関数が 「正しく計算しない(切り捨てを使う)事で、正しく(整数の積を)計算する」 と言う事を言いたいために引数がfloatの場合を持ち出したのですが かえってわかりづらくなったかもしれませんね すみません
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問