Microsoft Excel 用VBAライブラリ(ユーザー定義関数群)です
特徴
- N進数同士の四則演算(和算・減算・乗算・除算)を、N進数のまま演算します
- 内部的に浮動小数点数にキャストせずに演算します
- N進数→N進数変換を、小数点を含んだ状態で実行できます
こんな時に使います
N進数(10進数を含む)に対する演算を、ExcelをインストールしているPCであれば、どのPCでも動くワークブックを作りたい
このような問題は、簡単な数値(例えばF(hex)→1111(bin)のような変換等)であれば、Excel標準機能で計算可能です。
しかしながら、以下のような問題は、「BaseNNumericString」が解決します。
- Excel標準の演算機能(+, -, *, /)では精度が確保できない演算
- 小数点を含んだN進数同士の四則演算
- Excel標準の基数変換関数(BIN2HEX, HEX2BIN等)では扱いきれない大きな数値の基数変換
- 小数を含んだN進数の基数変換
動作環境
- Windows 7(64bit, 32bit) 以上
- Microsoft Excel 2013(64bit, 32bit) 以上
↑動作確認できた環境が上記であるというだけです。実際は動くかもしれません
使い方
Excelアプリの設定でマクロを有効にして下さい。
Excelマクロの有効化設定手順はこちら
あとは、Excelの標準関数と同様に使用できます。
具体的に役立つ場面を、このページでチュートリアル形式で説明しています。
API仕様
パラメータの説明は、上から順番に、第1,2,3…引数という順番で記載しています。
baseNAddition
加算
パラメータ:
val1 - 足される数(String型)
val2 - 足す数(String型)
radix - 基数(Optional) 省略した場合は、10とみなします
戻り値:
加算結果
パラメータが不正の場合は、以下に応じたCvErrを返却します
・val1 / val2 が空文字かNullの場合(エラーコードは#NULL!)
・radixが2~16以外か、val1 / val2 はn進値として不正の場合(エラーコードは#NUM!)
baseNMultiplication
乗算
パラメータ:
multiplicand - 被乗数(String型)
multiplier - 乗数(String型)
radix - 基数(Optional) 省略した場合は、10とみなします
戻り値:
乗算結果
パラメータが不正の場合は、以下に応じたCvErrを返却します
・multiplicand / multiplier が空文字かNullの場合(エラーコードは#NULL!)
・radixが2~16以外か、multiplicand / multiplier はn進値として不正の場合(エラーコードは#NUM!)
baseNDivision
除算の商
パラメータ:
dividend - 被除数(String型)
divisor - 除数(String型)
radix - 基数(Optional) 省略した場合は、10とみなします
limitOfFrcDigits - 求める小数点以下桁数の最大値(Optional) 省略した場合は、30とみなします
0を設定した場合は、小数点以下は求めません
(-)値を設定した場合は、その値を(-1)倍した整数桁数を残した状態で、除算を打ち切ります
ex:)
【前提】512 / 3 = 100 余り 212
【実行方法】x = baseNDivision("512", "3", 10, -2)
【結果】 x:100
戻り値:
除算の商
以下の場合は、エラーコードを返却します
・0割の場合(エラーコードは#DIV/0!)
・dividend / divisor の数値列内に、Long型で取り扱えない大きな数値がある場合(エラーコードは#NUM!)
・dividend / divisor が空文字かNullの場合(エラーコードは#NULL!)
・radixが2~16以外か、数値列はn進値として不正の場合(エラーコードは#NUM!)
baseNDivisionRem
除算の余り
パラメータ:
dividend - 被除数(String型)
divisor - 除数(String型)
radix - 基数(Optional) 省略した場合は、10とみなします
limitOfFrcDigits - 求める小数点以下桁数の最大値(Optional) 省略した場合は、30とみなします
0を設定した場合は、小数点以下は求めません
(-)値を設定した場合は、その値を(-1)倍した整数桁数を残した状態で、除算を打ち切ります
ex:)
【前提】512 / 3 = 100 余り 212
【実行方法】x = baseNDivisionRem("512", "3", 10, -2)
【結果】 x:212
戻り値:
除算の余り
以下の場合は、エラーコードを返却します
・0割の場合(エラーコードは#DIV/0!)
・dividend / divisor の数値列内に、Long型で取り扱えない大きな数値がある場合(エラーコードは#NUM!)
・dividend / divisor が空文字かNullの場合(エラーコードは#NULL!)
・radixが2~16以外か、数値列はn進値として不正の場合(エラーコードは#NUM!)
quotAndRemdOfBaseNDivision
除算の商と余り
この関数は、除算結果の余りを参照渡しされた変数remainderに格納して、
除算結果の商を返却することで、商と余りと一度に取得することを目的に使用します。
そのためユーザー定義関数としてワークシートから数式で呼び出しても、
呼び出した側のワークシートは変数remainderに格納された数値を確認できません。
VBによる開発時に初めて使用するものと理解して下さい。
パラメータ:
dividend - 被除数(String型)
divisor - 除数(String型)
radix - 基数(Optional) 省略した場合は、10とみなします
remainder - 余り(参照渡し)
limitOfFrcDigits - 求める小数点以下桁数の最大値(Optional) 省略した場合は、30とみなします
0を設定した場合は、小数点以下は求めません
(-)値を設定した場合は、その値を(-1)倍した整数桁数を残した状態で、除算を打ち切ります
ex:)
【前提】512 / 3 = 100 余り 212
【実行方法】x = quotAndRemdOfBaseNDivision("512", "3", 10, r, -2)
【結果】 x:100
r:212
戻り値:
パラメータのremainderに除算の余りを格納し、除算の商を返却します
以下の場合は、エラーコードを返却します
・0割の場合(エラーコードは#DIV/0!)
・dividend / divisor の数値列内に、Long型で取り扱えない大きな数値がある場合(エラーコードは#NUM!)
・dividend / divisor が空文字かNullの場合(エラーコードは#NULL!)
・radixが2~16以外か、数値列はn進値として不正の場合(エラーコードは#NUM!)
baseNConv
n進数をn進数に変換する
パラメータ:
baseNNumericStr - 変換元数値(String型)
fromRadix - 変換元数値の基数
toRadix - 変換先数値の基数
limitOfFrcDigits - 小数点以下の求める桁数(Optional)
戻り値:
パラメータが不正の場合は、以下に応じたCvErrを返却します
・fromRadix / toRadix が2~16以外か、baseNNumericStrはfromRadix進値として不正の場合(エラーコードは#NUM!)
・baseNNumericStrが空文字かNullの場合(エラーコードは#NULL!)
・limitOfFrcDigitsが(-)値 (エラーコードは#NUM!)
baseNMinus1sComplement
減基数の補数を得る
パラメータ:
baseNNumericStr - 変換元数値(String型)
radix - 基数
戻り値:
減基数の補数
パラメータが不正の場合は、以下に応じたCvErrを返却します
・radixが2~16以外か、数値列はn進値として不正の場合(エラーコードは#NUM!)
・数値列が空文字かNullの場合(エラーコードは#NULL!)
制限事項
用途によっては致命的なもの
- 遅いです。大量計算には向きません ※1
- セルに表示出来る計算結果は、符号と小数点文字含めて、32,767 文字までです ※2
- 除算でオーバーフローする場合があります ※3
- 扱える基数は2~16まで ※4
書式に関するもの
- 10進法でいう 10以上の数字は、10→A,11→B…,15→Fと、大文字アルファベットで記述します。小文字は使用できません。
- 小数点は “.” です
- 桁区切り文字 “,”等 は使用できません
- プラス記号 “+” は使用できません
- 指数表現の数値指定はできません
※1
Windows10 64bit, MS-Office 2016 64bit(CPU:Corei7-3770, RAM:16GB)の環境で、
除算は約 110[桁/s]、基数変換(小数の変換)においては約900[桁/s]程度の速度でした。
関数電卓代わりに使用する分には十分な計算速度ですが、
計算速度を意識するプログラム開発には向きません。
※2
計算結果をセルに表示させる場合に、この制限がかかってしまいます。
これはExcelの仕様に、「セルが含むことができる合計文字数は32,767 文字まで(出典1)」とある為です。
32,767文字を超える演算結果となった場合は、セルに「#VALUE!」と表示されます。
書式が正しいのに「#VALUE!」となってしまった場合は、この制限に該当していないかどうかを確認してください。
計算結果をセルに表示させない(具体的には、外部モジュールからの関数呼び出しの場合)は、この限りではありませんが、
返却値型をString型としているので、VBのString型の格納文字数制限( ‘およそ’ 20億とMicrosoftはいっています(出典2))までしか取り扱えません。
※3
以下3つのAPI(除算をする関数)にその可能性があります。
- baseNDivision
- baseNDivisionRem
- quotAndRemdOfBaseNDivision
理由は、除算処理内部で、除数と被除数をVBのLong型にキャストした状態で除算を行っているからです。
除数の場合は、10進数換算で、「-2,147,483,647~2,147,483,647」までセーフ、
被除数の場合は、ひっ算による除算中に「2,147,483,647」に収まらない数値が発生しない間はセーフとなります。
具体例でいうと、以下はセーフですが、
baseNDivision("2147483648", "2")
以下はアウトとなります(オーバーフローが発生します)。
baseNDivision("2147483648", "2147483647")
オーバーフローが発生した場合は、戻り値として「#NUM!」を返します。
書式が正しいのに「#NUM!」となってしまった場合は、この例に当てはまっていないかどうかを確認してください。
※4
17進数以上は扱えません。
対応しようとすれば、技術的に不可能ではないと思っていますが、
32進法や64進法は、数字の書式に関するルールに、世間一般的に”ほとんどはこれ”というものがなく、
また、代表的なルール同士は競合しがちです。(たとえば、10進法の 31 は Base32エンコード方式では 7 だけど、Base64エンコード方式では f (出典3))
その為この対応は面倒な上、混乱を招くと思っているので、今は保留しています。
License
GPL v3.0 ライセンスです。
詳しい内容は、PJのライセンスファイルを確認して下さい。