Base-N Numeric String

【VBA】N進数の四則演算・基数変換

Table of Contents

Poted on 2020-03-18

Base-N Numeric String

【VBA】N進数の四則演算・基数変換

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のライセンスファイルを確認して下さい。

出典

  1. 文字列型 (String) (Visual Basic)
  2. Excel の仕様および制限
  3. The Base16, Base32, and Base64 Data Encodings