LSetとユーザー定義型のコピー(100桁の足し算)
数の単位に「無量大数」というものがあります。
その桁数は10^68(10^88とする場合もあるよう)です。
VBAでこの無量大数の足し算をするにはどうしたら良いでしょうか。
ここではサンプルとして、100桁の数値を1桁ずつ足し上げていくVBAを紹介します。
そして、このサンプルVBAの中で、
RSetステートメント
LSetステートメント
Typeステートメント
LSetでユーザー定義型のコピー
これらを使用しています。
数値データ型の数値範囲
データ型 | 名称 | 格納できる範囲 |
Integer | 整数型 | -32,768 ~ 32,767 |
Long | 長整数型 | -2,147,483,648 ~ 2,147,483,647 |
LongLong | 64ビット符号付き数値 | -9223372036854775808 ~ 9223372036854775807 ※64ビットプラットフォームのみで有効な宣言型 |
Single | 単精度浮動小数点数型 | -3.402823E38 ~ -1.401298E-45(負の値) 1.401298E-45 ~ 3.402823E38(正の値) |
Double | 倍精度浮動小数点数型 | -1.79769313486232E308 ~ -4.94065645841247E-324(負の値) 4.94065645841247E-324 ~ 1.79769313486232E308(正の値) |
Currency | 通貨型 | -922,337,203,685,477.5808 ~ 922,337,203,685,477.00 |
Decimal | 10進数データ型 | スケールが0 (小数部がない) の場合の利用可能な最大値は、 +/-79,228,162,514,264,337,593,543,950,335
になります。 小数点以下の桁数が28の場合、最大値は +/-ない場合、最小値0以外の値は、 +/-0.0000000000000000000000000001 です。 |
いずれにしても、整数値として正確に表すことのできる桁数は100桁には遠く及びません。
100桁数値の足し算VBA
Option Explicit
Const MaxDigits As Long = 100 '入力の最大桁数
Type tpA
tpA1 As String * MaxDigits
End Type
Type tpB
tpB1(1 To MaxDigits) As String * 1
End Type
'大きな文字列数値の足し算
Function AddBigNumber(ByVal arg1 As String, _
ByVal arg2 As String) As String
'LSetで構造体から構造体の配列にコピー
Dim b1 As tpB, b2 As tpB
LSet b1 = Str2Type(arg1)
LSet b2 = Str2Type(arg2)
'一桁ずつ足し上げていく
Dim i As Long, tmp As String
Dim ans(MaxDigits) As String 'インデックス0は桁上がり用
For i = MaxDigits To 1 Step -1
If Trim(b1.tpB1(i) & b2.tpB1(i)) = "" Then Exit For
tmp = Str2Num(ans(i)) _
+ Str2Num(b1.tpB1(i)) + Str2Num(b2.tpB1(i))
ans(i) = Right$(tmp, 1)
ans(i - 1) = IIf(Len(tmp) = 1, "", Left$(tmp, 1))
Next
AddBigNumber = Join(ans, "")
End Function
'文字列を構造体に入れて返す
Function Str2Type(ByVal str As String) As tpA
RSet Str2Type.tpA1 = str
End Function
'文字列の数値化:スペースを0にする
Function Str2Num(ByVal str As String) As Long
Str2Num = IIf(IsNumeric(str), str, 0)
End Function
100桁数値の足し算VBAの使い方と結果
Sub sample()
Dim a1 As String, a2 As String
a1 = "9999999999987654321098765432109876543210987654321098765432109876543210"
a2 = "123456789012345678901234567890123456789012345678901234567890"
Debug.Print AddBigNumber(a1, a2)
a1 = "1"
a2 = "99999999999999999999999999999999999999999999999999"
Debug.Print AddBigNumber(a1, a2)
a1 = "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
a2 = "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
Debug.Print AddBigNumber(a1, a2)
End Sub
イミディエイト ウィンドウに、
10000000000111111111111111111111111111111111111111111111111111111111100
100000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110
100桁数値の足し算VBAの解説
RSet ステートメント
文字列が文字列変数よりも長い場合、 RSetは左端から文字列変数の長さの文字だけを文字列変数に格納します。
LSet ステートメント
文字列が文字列変数よりも長い場合、 LSetは左端から文字列変数の長さの文字だけを文字列変数に格納します。
Type ステートメント
普通の変数は、1つの値しか入れられませんが、
ユーザー定義型は、複数の異なるデータ型を入れる事が出来ます。
プログラミング言語での一般的な呼び方としては、構造体とも呼ばれます。
第110回.ユーザー定義型・構造体(Type)|VBA入門
ユーザー定義型変数のコピー:TypeとLSet
特定のデータ型用に予約されているスペースに別のデータ型のデータをコピーした場合、予期しない結果になることがあります。
今回は、これを承知の上でのサンプルVBAです。
以下は、桁数を少なくして見やすくした場合の例です。
Type tpA
tpA1 As String * 5
End Type
Type tpB
tpB1(4) As String * 1
End Type
Sub sample()
Dim a As tpA
Dim b As tpB
RSet a.tpA1 = "123"
LSet b = a
Stop
End Sub
RSet a.tpA1 = "123"
a.tpA1に右寄せで"123"と入ります。
5文字がString * 1の配列に入ります。
上記VBAの参考ページ
Left関数 , LeftB関数
同じテーマ「マクロVBA技術解説」の記事
列幅・行高をDPI取得しピクセルで指定する
VBAでWMIの使い方について
アクティブシート以外のWindowを設定できるWorksheetView
LSetとユーザー定義型のコピー(100桁の足し算)
省略可能なVariant引数の参照不可をラップ関数で利用
ブックのいろいろな開き方(GetObject,参照設定,アドイン)
入力規則への貼り付けを禁止する
Select Caseでの短絡評価(ショートサーキット)の使い方
RangeオブジェクトのFor EachとAreasについて
画像が行列削除についてこない場合の対処
新関数SORTBYをVBAで利用するラップ関数を作成
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- LSetとユーザー定義型のコピー(100桁の足し算)
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。