きっかけ
PowerAutomate子フロー:指数関数 の作成にあたり、計算結果が指数関数的に増えることをふまえ、扱える数値の限界を確認しました。
coPilotに聞いたところ、PowerAutomateの整数型は64ビット符号付き整数(Int64)で扱われ、922京(19桁)まで扱えるものの、公式情報はないとのことでした。
Excelでも16桁以上の数値を入れても16桁目以降がゼロ埋めされる事象もあるとのこで、実際どうなのか確認したので記事にします。
2のべき乗数と整数の関係
64ビット整数で扱われるということで、2の63乗までの数値一覧を記載します。
| 指数(0-31) | 整数値 | 指数(32-63) | 整数値 | |
|---|---|---|---|---|
| 0 | 1 | 32 | 4,294,967,296 | |
| 1 | 2 | 33 | 8,589,934,592 | |
| 2 | 4 | 34 | 17,179,869,184 | |
| 3 | 8 | 35 | 34,359,738,368 | |
| 4 | 16 | 36 | 68,719,476,736 | |
| 5 | 32 | 37 | 137,438,953,472 | |
| 6 | 64 | 38 | 274,877,906,944 | |
| 7 | 128 | 39 | 549,755,813,888 | |
| 8 | 256 | 40 | 1,099,511,627,776 | |
| 9 | 512 | 41 | 2,199,023,255,552 | |
| 10 | 1,024 | 42 | 4,398,046,511,104 | |
| 11 | 2,048 | 43 | 8,796,093,022,208 | |
| 12 | 4,096 | 44 | 17,592,186,044,416 | |
| 13 | 8,192 | 45 | 35,184,372,088,832 | |
| 14 | 16,384 | 46 | 70,368,744,177,664 | |
| 15 | 32,768 | 47 | 140,737,488,355,328 | |
| 16 | 65,536 | 48 | 281,474,976,710,656 | |
| 17 | 131,072 | 49 | 562,949,953,421,312 | |
| 18 | 262,144 | 50 | 1,125,899,906,842,624 | |
| 19 | 524,288 | 51 | 2,251,799,813,685,248 | |
| 20 | 1,048,576 | 52 | 4,503,599,627,370,496 | |
| 21 | 2,097,152 | 53 | 9,007,199,254,740,992 | |
| 22 | 4,194,304 | 54 | 18,014,398,509,481,984 | |
| 23 | 8,388,608 | 55 | 36,028,797,018,963,968 | |
| 24 | 16,777,216 | 56 | 72,057,594,037,927,936 | |
| 25 | 33,554,432 | 57 | 144,115,188,075,855,872 | |
| 26 | 67,108,864 | 58 | 288,230,376,151,711,744 | |
| 27 | 134,217,728 | 59 | 576,460,752,303,423,488 | |
| 28 | 268,435,456 | 60 | 1,152,921,504,606,846,976 | |
| 29 | 536,870,912 | 61 | 2,305,843,009,213,693,952 | |
| 30 | 1,073,741,824 | 62 | 4,611,686,018,427,387,904 | |
| 31 | 2,147,483,648 | 63 | 9,223,372,036,854,775,808 |
①「変数を初期化する」の挙動確認
Excelで扱う上限が15桁ということで、2の49乗(約562兆、15桁)から値設定が正しく動作するか確認しました。

結果
2の54乗(約1.8京、17桁)までは指定値が出力に反映されましたが、2の55乗(約3.6京、17桁)以降は指定値が丸められて出力されました。

②「配列に変数追加」の挙動確認
①の結果ふまえ、2の49乗~54乗までを配列に追加する処理を確認しました。

結果
③-1)極端な桁違いの計算:1加算
②配列を流用し、各値に1を加算する処理を行います。
「選択」で以下の通り指定します。
- 開始:
@{variables('2の指数配列')} - マップ:(式)
@add(item(),1)
結果
2の53乗(約9007兆、16桁)以降は加算処理されませんでした。

③-2)極端な桁違いの計算:1減算
②配列を流用し、各値に1を減算する処理を行います。
「選択」で以下の通り指定します。
- 開始:
@{variables('2の指数配列')} - マップ:(式)
@add(item(),1)
結果
2の54乗(約1.8京、17桁)は減算処理されませんでした。

④-1)15桁の2つの乱数の加算
以下のフローにて2つの15桁の数値を作成して、それぞれを加算する処理を10回行い、計算結果が正しいかを判定します。

- 繰り返し:
@{range(1,10)} - 値1作成:
@{add(mul(rand(100000000,999999999),1000000),rand(0,999999))} - 値2作成:
@{add(mul(rand(100000000,999999999),1000000),rand(0,999999))} - 加算:
@{add(outputs('値1作成'),outputs('値2作成'))}
rand関数は10桁未満の制約があるため、9桁乱数を15桁化し、6桁乱数を加えてます。
結果
桁超えするもの含め、正しく加算されました(運要素ありますが…)
④-2)16桁の2つの乱数の加算
④-1の計算式を変えて16桁同士を加算する処理を10回行い、計算結果が正しいかを判定します。
結果
10件中、6件は計算結果が誤ってました。
桁超えしてもあってるもの、桁超えしなくても間違ってるものがありました。
④-3)15桁と16桁の2つの乱数の加算
④-1の計算式を変えて15桁と16桁を加算する処理を10回行い、計算結果が正しいかを判定します。
結果
10件中、1件は計算結果が誤ってました。
誤ってたものは桁超えしてないものの、計算結果が2の53乗(9007兆、16桁)を超えてました。
推察
③-1、④-3の試験結果ふまえると2の53乗(9007兆、16桁)以上の数値処理は誤った結果を含む可能性があります。
おなじMicrosoftのソフトであるExcelも15桁までしか扱えない点もふまえ、安全性を考えると整数値は15桁(50bit)までに制限するのが無難だと感じました。
正確な情報をお持ちの方がいれば、ぜひご教示ください🙇♂️
