C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: For next で乗数


(過去ログ 173 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■99719 / inTopicNo.1)  For next で乗数
  
□投稿者/ エム (1回)-(2022/05/18(Wed) 23:40:04)

分類:[.NET 全般] 



乗数は^を使えばいいのですがそれを使わずにFor Next 繰り返しの処理で乗数(aのb乗)を作成するにはどうしたりいいですか?


引用返信 編集キー/
■99720 / inTopicNo.2)  Re[1]: For next で乗数
□投稿者/ WebSurfer (2483回)-(2022/05/18(Wed) 23:46:37)
No99719 (エム さん) に返信

> 乗数は^を使えばいいのですがそれを使わずにFor Next 繰り返しの処理で乗数(aのb乗)を作成するにはどうしたりいいですか?

「乗数は^を使えばいい」とか何の話をしているのかな?
引用返信 編集キー/
■99721 / inTopicNo.3)  Re[1]: For next で乗数
□投稿者/ 魔界の仮面弁士 (3365回)-(2022/05/19(Thu) 01:15:42)
No99719 (エム さん) に返信
> 乗数は^を使えばいいのですがそれを使わずにFor Next 繰り返しの処理で乗数(aのb乗)を作成するにはどうしたりいいですか?

何故、^ を使いたくないのですか?

質問の意図が不明ですが、「b が自然数」なのであれば
普通の累乗計算なので、御自身で書かれたように、
For Next で a を b 回乗じれば求められますよね。
http://web.sfc.keio.ac.jp/~tsaito/ITWS/Lec03.html
 
「自然数」ではなく「整数」だった場合も基本的には同じです。
負数の場合は掛け算ではなく割り算になるという点と、
a と b の両方が 0 だった場合を弾く必要がある点のみ
気をつけておきましょう。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=99571
 
しかし、わざわざ手順を掲示板で質問するということは、
今回は累乗計算ではなく、「b が小数」の冪乗計算なのでしょうか?
 
その場合は b を分数化し、その分母値の冪根を a に対して
求める形で算出したりもできますが(対数にする手法もあり)
実際にはわざわざ遠回りせずとも、最初から Math.Pow で処理したほうが話が早そうです。
引用返信 編集キー/
■99722 / inTopicNo.4)  Re[1]: For next で乗数
□投稿者/ Azulean (1241回)-(2022/05/19(Thu) 07:31:06)
2022/05/19(Thu) 07:34:08 編集(投稿者)

No99719 (エム さん) に返信
> 乗数は^を使えばいいのですがそれを使わずにFor Next 繰り返しの処理で乗数(aのb乗)を作成するにはどうしたりいいですか?

「あえて繰り返しで実装する」ということは、たぶんアルゴリズムの理解を促す課題なのではないか? と思いますね。


// すでにリンクされているけど、 No99571 と言語も含めて同じなのは、この課題(演習)が流行っているのだろうか…。
引用返信 編集キー/
■99723 / inTopicNo.5)  Re[2]: For next で乗数
□投稿者/ 魔界の仮面弁士 (3366回)-(2022/05/19(Thu) 10:32:37)
No99722 (Azulean さん) に返信
>> 乗数は^を使えばいいのですがそれを使わずにFor Next 繰り返しの処理で乗数(aのb乗)を作成するにはどうしたりいいですか?
こっちは、For ループによる具体的なコード例のある URL を紹介済みなので、元質問者の再登場待ちとして:


> 「あえて繰り返しで実装する」ということは、たぶんアルゴリズムの理解を促す課題なのではないか? と思いますね。
累乗計算や冪乗計算は、専用の演算子やメソッドが既に準備されているので、
それを課題にすると、「車輪の再発明」になってしまうんですよね…。

ループ計算の課題としては、個人的には階乗計算の方が良いのではないかと思ってみたり。

ついでに階乗から発展して、ガンマ関数まで拡張させた実装例がこちら。
本題からは大きく外れてしまいますが。
http://numeric.world.coocan.jp/computer/vb/gamma.htm
引用返信 編集キー/
■99729 / inTopicNo.6)  Re[1]: For next で乗数
□投稿者/ オーガニックダーク (2回)-(2022/05/19(Thu) 21:12:45)
No99719 (エム さん) に返信

Function Power(a As Integer, b As Integer) As Integer
    Dim p = 1
    
    For i = 1 To b
        p = p * a
    Next
    
    Return p
End Function

パワー!

引用返信 編集キー/
■99730 / inTopicNo.7)  Re[2]: For next で乗数
□投稿者/ 魔界の仮面弁士 (3367回)-(2022/05/19(Thu) 23:02:29)
No99729 (オーガニックダーク さん) に返信
> ■No99719 (エム さん) に返信
> Function Power(a As Integer, b As Integer) As Integer

Integer が取りうる値の範囲は、 -2,147,483,648 以上 2,147,483,647 以下の範囲ですので
冪乗計算の戻り値の型が As Integer だと心許ないかも。

仮に、引数の範囲を a As Byte, b As Byte という範囲に狭めたとしても、
a = 2, b = 31 の場合(答えは 2,147,483,648) や
a = 255, b = 4 の場合(答えは 4,228,250,625) で計算させると
簡単に Integer の範囲を超えてしまうわけで…。


ということで、戻り値の型をあえて Double にしてみました。

Public Function Power(a As Short, b As Short) As Double
  Dim p As Double = 1.0
  If b > 0S Then
    For n = 1 To b
      p *= a '冪指数が正の整数の場合は、乗算を繰り返す
    Next
  ElseIf b < 0S Then
    For n = b To -1
      p /= a '冪指数が負の整数の場合は、除算を繰り返す
    Next
  ElseIf a = 0S Then
    ' 0 の 0 乗を「1」として扱う処理系( a ^ 0 = 1 のルール)や
    ' 0 の 0 乗を「0」として扱う処理系( 0 ^ b = 0 のルール)もあるが、
    ' 0 の 0 乗は本来未定義なので、ここでは NaN を返すことにする
    p = Double.NaN
  End If
  Return p
End Function


なお、a = 0, b < 0 の場合は、正の無限大が Return されることになります。
引用返信 編集キー/
■99733 / inTopicNo.8)  Re[3]: For next で乗数
□投稿者/ 魔界の仮面弁士 (3368回)-(2022/05/20(Fri) 11:12:17)
No99730 (魔界の仮面弁士) に追記
>> Function Power(a As Integer, b As Integer) As Integer
> Integer が取りうる値の範囲は、 -2,147,483,648 以上 2,147,483,647 以下の範囲ですので
> 冪乗計算の戻り値の型が As Integer だと心許ないかも。

引数を Integer のままにしつつ、結果を Double ではなく BigInteger 型として返却してみるサンプル。
※ .NET Framework 4 以降が対象

これなら、巨大数であっても正しく算出できます。


' 「255 ^ 255」や「Math.Pow(255, 255)」で算出した場合は
' Double の最大値を超えてしまい、∞ という結果が返されますが、
' BigInteger 型を使えば、「Power(255, 255)」の答えとなる 562 桁の整数も
' 桁溢れすることなく保持できます。
'
'
' MsgBox((255 ^ 255).ToString("N0"))
' MsgBox(Power(255, 255).ToString("N0"))
'


' BigInteger 型を使うためには、「System.Numerics」を参照設定しておく必要があります。
Public Function Power(a As Integer, b As Integer) As System.Numerics.BigInteger
  Dim p = System.Numerics.BigInteger.One
  If a = 0 Then
    If b = 0 Then
      Throw New ArgumentOutOfRangeException("b", "a と b が共に 0 の結果は不定")
    ElseIf b < 0 Then
      Throw New OverflowException("a = 0, b < 0 の結果は +∞")
    End If
    Return p
  ElseIf a = 1 Then
    Return p
  ElseIf a = -1 Then
    Return If(b Mod 2 = 0, p, a)
  ElseIf b > 0 Then
    For n = 1 To b
      p *= a
    Next
  ElseIf b < 0 Then
    For n = 1 To -b
      p /= a
    Next
  End If
  Return p
End Function


上記の実装例で、「ElseIf a = 1 Then」および「ElseIf a = -1 Then」の部分は
実際には無くても計算できるのですが、この場合は結果が分かり切っているため、
ループを省くための高速化処置として追加してあります。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -