![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
半分数学の問題なのですが、考え方はプログラミングなのでこちらのカテゴリで質問しました。
大学で計算の可能性という講義を受けています。
この講義ではwhileプログラムというプログラムを使って計算の可能性を調べる講義です。
そこで
足し算、引き算のみを用いて割り算、剰余、指数、対数を計算する手続きを作れという問題が出されました。
割り算、剰余は
procedure z = x div y:
begin u1 := x; u2 := y; z := 0;
while u1 >= u2 do
begin u1 := u1 - u2;
z := z + 1;
end
end
procedure z = x mod y:
begin u1 := x; u2 := y; z := 0;
while u1 >= u2 do
begin u1 := u1 - u2;
z := u1;
end
end
という手続きでできそうだとわかりました。
(C言語で似たような関数をつくり確認しました。)
しかし、指数と対数を求める手続き
procedure z := x ** y:
と
procedure z := log2 x:
がどうすればよいか分かりません。
この2つを教えていただけないでしょうか?
プログラムの流れが分かればいいので足し算引き算のみ使用しているならC言語でもいいです!
よろしくお願いします。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_14.png?e8efa67)
No.3ベストアンサー
- 回答日時:
C言語で作成しました。
動作確認済みです。----------------------------------------
#include <stdio.h>
#include <stdlib.h>
// x,yは自然数である。従ってx>0,y>の整数とする。
//[while]に敬意を表し、for文でなく、while文で
//プログラムを作成する
// x*yの結果を返す関数
// これは、powerから呼ばれる補助関数
int multiply(int x,int y)
{
int i = 1;
int ans = x;
//xをy回たせば、掛け算になる
while(i < y){
ans = ans + x;
i++;
}
return ans;
}
// x**yの結果を返す関数
int power(int x,int y)
{
//x*xをy回繰り返す。
int ans = x;
int i = 1;
//x*xをy回繰り返すと、x**yになる
while(i < y){
ans = multiply(ans,x);
i++;
}
return ans;
}
// x/yを返す関数
// これは、log2から呼ばれる補助関数
int divide(int x,int y)
{
int ans = 0;
//xからy回引き算すると割り算になる
while(x >= y){
x = x - y;
ans++;
}
return ans;
}
// log2 x を返す関数 (2を底とするxの対数)
int log2(int x)
{
int ans = 0;
//xを2で1になるまで割る。(1より大きい間実行)
//その回数が求める解
while (x > 1){
ans++;
// y/2を求める
x = divide(x,2);
}
return ans;
}
int main(int argc , char **argv)
{
int ans;
ans = power(2,4);
printf("2**4=%d\n",ans);
ans = log2(16);
printf("log2 16=%d\n",ans);
}
No.4
- 回答日時:
#2 の補足のところに対してですが, 「計算の可能性」という表現からすると, おそらく while プログラムは「計算のモデル」として使っているんじゃないかなぁという気がします. そういう意味では, まさに「数学で使うことを目的にしている」といっていいかと思います.
計算モデルとしては Turing機械がもっとも一般的に使われていると思いますが, 正直いって「実際に使うととっても面倒」なので, より記述しやすい (かつ等価な) モデルを使うこともあります. こちらだと普通は RAM (Random Access Machine) のような気がしますが, while プログラムでもほぼ同じです.
No.1
- 回答日時:
うーん。
自信ない。現状x,y,zが整数になっているけど,それ以外のケースってどうやったらいいんだろう・・・
とりあえず整数だけに限る。
ある関数に含まれる全ての関数が加算・減算のみで出来ているなら
その関数は加算・減算のみで出来る、よね?多分・・・・A
======================================
一気に累乗を考えると混乱するので,
累乗を掛け算で示す。
x**y = x * x * x *・・・
ってのをy回繰り返したものだよね?
x * yってどうやるかって言ったら(yが整数なら)
xをy回足せばいい。
C#が自分は慣れているのでC#で書くなら
multiple(x,y) = x * yは以下のように書く。
namespace Q3694102
{
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine(multiple(2,3).ToString()); /* 表示するだけ */
System.Console.ReadKey(true); /* キーを押すまで待機 */
}
public static int multiple(int x,int y)
{
int z = 0;
for (int i=y;i>0;i--){
z = z + x;
}
return z;
}
}
となる。
==========================================================
pow関数は
namespace Q3694102
{
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine(pow(2,3).ToString()); /* 表示するだけ */
System.Console.ReadKey(true); /* キーを押すまで待機 */
}
public static int pow(int x,int y){
int z = 1;
for(int i = y;i>0;i--){
z = multiple(z,x);
}
}
public static int multiple(int x,int y)
{
int z = 0;
for (int i=y;i>0;i--){
z = z + x;
}
return z;
}
}
となるだろう。
====================
Aがあるので,後は展開するだけ。
変数のスコープが違うから同じ名前の変数が混在していたが,
一つに纏めるとなったら呼び出し元の同名変数を書き換えないように,
仮引数用の変数に書き換える
namespace Q3694102
{
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine(pow(2,3).ToString()); /* 表示するだけ */
System.Console.ReadKey(true); /* キーを押すまで待機 */
}
public static int pow(int x,int y){
int z = 1;
for(int i = y;i>0;i--){
//multiple関数の展開,ここから
int m = 0;
for (int j = x;j>0;j--){
m = m + z;
}
z = m;
}
return z;
}
}
}
===============================
次,対数。
z := log2 x:
要するに,
2**z = x;
となるような整数zをループ回して探せ、と。
namespace Q3694102
{
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine(log(2,3).ToString()); /* 表示するだけ */
System.Console.ReadKey(true); /* キーを押すまで待機 */
}
public static int pow(int x,int y){
int z = 1;
for(int i = y;i>0;i--){
//multiple関数の展開,ここから
int m = 0;
for (int j = x;j>0;j--){
m = m + z;
}
z = m;
}
return z;
}
public static int log(int x,int y){
int z = 0;
int i = 1;
while(true){ /* 本当はオーバーフローとか気にしないといけない。*/
if (pow(x,i) > y){
break;
}
z = z + 1;
i = i + 1;
}
return i - 1;
}
}
}
後はこれを展開するだけ。面倒くさいけど。
==================================
x,yが整数でなかったときの考察。
桁が許せば,になるけれど,
xとかyとかzがコンピュータであらわせる小数ってとき
x = a[0] * 2**(0) + a[1] * 2**(-1) + a[2] * 2**(-2)
とかになる。
上の例ならxに2**2掛ければ整数になるんじゃね?
zが整数でないとき。
うーん。
実数同士の掛け算・割り算が使えそうなら
2分法みたいので狭める手が使えるとは思うんだけど。
==================================
x,yが整数でなかったときの考察。
桁が許せば,になるけれど,
xとかyとかzがコンピュータであらわせる小数ってとき
x = a[0] * 2**(0) + a[1] * 2**(-1) + a[2] * 2**(-2)
とかになる。
上の例ならxに2**2掛ければ整数になるんじゃね?
zが整数でないとき。
うーん。
実数同士の掛け算・割り算が使えそうなら
2分法みたいので狭める手が使えるとは思うんだけど。
===========================
●x,yが負の時
●そもそもそんな解が存在しないとき。
log2(-1)とか
面倒くさいので考えてません。
============================
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# ある線が円の範囲に入っているかの計算 1 2022/12/07 16:14
- 物理学 統計力学における平衡状態の定義について 4 2022/12/27 01:47
- C言語・C++・C# C言語 3 2022/10/04 15:07
- 数学 (4)のim(T)をu1,u2,u3の線型結合で表せ、という問題がわからないです。回答を見ると私の解 2 2023/05/31 22:14
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- 物理学 弦の振幅が次式で与えられる波はどのような波でしょうか。 u1= -Asin(2πvt-2πx/λ) 1 2023/03/02 17:20
- Ruby VBA 2 2023/01/14 14:14
- 数学 線形代数の正規直行系についての問題がわからないです。 1 2022/07/16 11:20
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- Java javaの質問です 次の機能を有するメソッド4つを自クラスに作成し、実装したいです 【機能】 足し算 1 2022/06/15 17:49
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
複数桁10進数の*桁目だけを抽出...
-
C言語での引数の省略方法
-
市松模様
-
構造体の勉強中です 合計点の高...
-
#define _CRT_SECURE_NO_WARNIN...
-
「{ } で囲むだけ」は正しい?
-
C言語初心者です、、、お助けく...
-
C言語の構造体について
-
C言語でDxlibを使って3x3の奇数...
-
C言語における対称行列の作り方...
-
このプログラミング誰か教えて...
-
CStringの配列要素を関数で受け...
-
if と配列の組み合わせ
-
因数分解を行うプログラムについて
-
式は定数値が必要です」という...
-
C言語 エラーの原因がわからな...
-
数字列を3桁ごとにカンマで区切...
-
C言語のサイコロシミュレート
-
ファイルから読みこむ方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
C言語 エラーの原因がわからな...
-
c++でテンプレートのコードでわ...
-
(int *)の意味
-
ラップ関数とはどんなものですか?
-
数字列を3桁ごとにカンマで区切...
-
c言語のリダイレクトによる円...
-
比較回数と交換回数表示について
-
実数の整数部,小数部の取得
-
if と配列の組み合わせ
-
構造体の勉強中です 合計点の高...
-
PowerShellがうまくいかない
-
c言語の配列を使ってサイコロを...
-
課題でつまってます・・・
-
C言語のサイコロシミュレート
-
エラー 添字が付けられた値が、...
おすすめ情報