本ページには広告が含まれています。
目次
単精度浮動小数点数、倍精度浮動小数点数の数値をIEEE754形式で表された2進数の文字列に、もしくはIEEE754形式で表された2進数の文字列を単精度浮動小数点数、倍精度浮動小数点数の数値に変換します。
- 構文
- UString = IEEE754.singleToBin( dec )
- Double = IEEE754.binToSingle( bin )
- UString = IEEE754.doubleToBin( dec )
- Double = IEEE754.binToDouble( bin )
- UString = IEEE754.singleToBin( dec )
- 引数
- dec 必須
- 10進数
- bin 必須
- 2進数
- 戻り値
プログラム
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// bin : 2進数
// 【戻り値】
//
//////////////////////////////////////////////////
MODULE IEEE754
FUNCTION singleTobin(dec)
DIM s = IIF(dec >= 0, "0", "1")
DIM integer = decToBin(SPLIT(dec, ".")[0])
DIM decimal = SPLIT(dec, ".")[1]
decimal = "0." + decimal
decimal = decToBin(decimal)
DIM bin = integer + COPY(decimal, POS(".", decimal))
bin = leftTrim(bin, "0")
IF COPY(bin, 1, 1) = "." THEN bin = "0" + bin
DIM e = POS(".", bin) - POS("1", bin)
e = e - IIF(e > 0, 1, 0) + 127
e = decToBin(e)
e = COPY(e, LENGTH(e) - 8 + 1)
DIM m = strPad(COPY(leftTrim(REPLACE(bin, ".", ""), "0"), 2, 24), 24, "0", RIGHT)
DIM keta = 24
WHILE COPY(m, keta, 1) = "1"
keta = keta - 1
WEND
m = strPad(COPY(leftTrim(REPLACE(bin, ".", ""), "0"), 2, keta - 1), keta - 1, "0", RIGHT) + "1" + strRepeat("0", 24 - keta)
m = COPY(m, 1, 23)
RESULT = s + e + m
FEND
FUNCTION binToSingle(bin)
DIM s = IIF(COPY(bin, 1, 1) = 0, 1, -1)
DIM e = COPY(bin, 2, 8)
DIM m = COPY(bin, 10)
e = binToDec(e, FALSE) - 127
m = "1" + m
IFB e < 0 THEN
m = "0." + strRepeat("0", ABS(e+1)) + m
ELSE
m = COPY(m, 1, e + 1) + "." + COPY(m, e + 2)
ENDIF
RESULT = s * binToDec(m, FALSE)
FEND
FUNCTION doubleToBin(dec, bool = FALSE)
DIM s = IIF(dec >= 0, "0", "1")
DIM integer = decToBin(SPLIT(dec, ".")[0])
DIM decimal = SPLIT(dec, ".")[1]
decimal = "0." + decimal
decimal = decToBin(decimal)
DIM bin = integer + COPY(decimal, POS(".", decimal))
bin = leftTrim(bin, "0")
IF COPY(bin, 1, 1) ="." THEN bin = "0" + bin
DIM e = POS(".", bin) - POS("1", bin)
e = e - IIF(e > 0, 1, 0) + 1023
e = decToBin(e)
e = COPY(e, LENGTH(e) - 11 + 1)
IFB bool THEN
DIM m = strPad(COPY(leftTrim(REPLACE(bin, ".", ""), "0"), 2, 53), 53, "0", RIGHT)
DIM keta = 53
WHILE COPY(m, keta, 1) = "1"
keta = keta - 1
WEND
m = strPad(COPY(leftTrim(REPLACE(bin, ".", ""), "0"), 2, keta - 1), keta - 1, "0", RIGHT) + "1" + strRepeat("0", 53 - keta)
m = COPY(m, 1, 52)
ELSE
m = strPad(COPY(leftTrim(REPLACE(bin, ".", ""), "0"), 2, 52), 52, "0", RIGHT)
ENDIF
RESULT = s + e + m
FEND
FUNCTION binToDouble(bin)
DIM s = IIF(COPY(bin, 1, 1) = 0, 1, -1)
DIM e = COPY(bin, 2, 11)
DIM m = COPY(bin, 13)
e = binToDec(e, FALSE) - 1023
m = "1" + m
IFB e < 0 THEN
m = "0." + strRepeat("0", ABS(e+1)) + m
ELSE
m = COPY(m, 1, e + 1) + "." + COPY(m, e + 2)
ENDIF
RESULT = s * binToDec(m, FALSE)
FEND
ENDMODULE
//////////////////////////////////////////////////
// 【引数】
// bin : 2進数
// signFlg : 符号付きならばTrue
// 【戻り値】
// 10進数に変換した値
//////////////////////////////////////////////////
FUNCTION binToDec(bin, signFlg = TRUE)
DIM dec = 0
DIM decimalFlg = IIF(POS(".", bin), TRUE, FALSE)
IFB COPY(bin, 1, 1) = "1" AND signFlg THEN
DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
DIM lsb = IIF(decimalFlg, POS(".", bin) - LENGTH(bin), 0)
DIM dec2 = POWER(2, msb) - 1
FOR i = -1 TO lsb STEP -1
dec2 = dec2 + POWER(2, i)
NEXT
DIM a = binToDec(bin, FALSE)
DIM b = dec2
dec = -1 * (bitXor(a, b) + POWER(2, lsb))
ELSE
IFB decimalFlg THEN
DIM integer = COPY(bin, 1, POS(".", bin) - 1)
DIM decimal = COPY(bin, POS(".", bin) + 1)
FOR i = 1 TO LENGTH(decimal)
dec = dec + COPY(decimal, i, 1) * POWER(2, -1 * i)
NEXT
ELSE
integer = bin
ENDIF
FOR i = 1 TO LENGTH(integer)
dec = dec + COPY(integer, i, 1) * POWER(2, LENGTH(integer) - i)
NEXT
ENDIF
RESULT = dec
FEND
//////////////////////////////////////////////////
// 【引数】
// arg1 : 数値1(10進数)
// arg2 : 数値2(10進数)
// 【戻り値】
// 2つの数値のビット毎の排他的論理和
//////////////////////////////////////////////////
FUNCTION bitXor(arg1, arg2)
DIM args[1] = arg1, arg2
DIM bins[1]
DIM decimals[1]
DIM integers[1]
DIM keta[1]
IFB ABS(arg1) <> arg1 OR ABS(arg2) <> arg2 THEN
RESULT = ERR_VALUE
EXIT
ENDIF
FOR i = 0 TO 1
bins[i] = decToBin(args[i])
decimals[i] = 0
IFB POS(".", bins[i]) <> 0 THEN
integers[i] = COPY(bins[i], 1, POS(".", bins[i]) - 1)
decimals[i] = COPY(bins[i], POS(".", bins[i]) + 1)
ELSE
integers[i] = bins[i]
ENDIF
NEXT
keta[0] = IIF(LENGTH(integers[0]) > LENGTH(integers[1]), LENGTH(integers[0]), LENGTH(integers[1]))
integers[0] = strPad(integers[0], keta[0], "0", LEFT)
integers[1] = strPad(integers[1], keta[0], "0", LEFT)
keta[1] = IIF(LENGTH(decimals[0]) > LENGTH(decimals[1]), LENGTH(decimals[0]), LENGTH(decimals[1]))
decimals[0] = strPad(decimals[0], keta[1], "0", RIGHT)
decimals[1] = strPad(decimals[1], keta[1], "0", RIGHT)
DIM bin = ""
FOR i = 1 TO keta[0]
bin = bin + (VAL(COPY(integers[0], i, 1)) XOR VAL(COPY(integers[1], i, 1)))
NEXT
bin = bin + "."
FOR i = 1 TO keta[1]
bin = bin + (VAL(COPY(decimals[0], i, 1)) XOR VAL(COPY(decimals[1], i, 1)))
NEXT
RESULT = binToDec(bin)
FEND
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// signFlg : 符号付きならばTrueを指定
// digits : 変換した2進数の桁数合わせを自動で行うかを示すブール値、もしくは桁数を表す数値(8,16,24,32,64のいずれか)を指定
// recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
// 【戻り値】
// 2進数に変換した値
//////////////////////////////////////////////////
FUNCTION decToBin(dec, signFlg = TRUE, digits = FALSE, recursive = 1)
IFB dec < 0 AND signFlg = FALSE THEN
RESULT = ERR_VALUE
EXIT
ENDIF
IFB VARTYPE(digits) <> VAR_BOOLEAN AND digits < CEIL(LOGN(2, ABS(dec))) + IIF(dec < 0, 1, 0) THEN
RESULT = ERR_VALUE
EXIT
ENDIF
DIM bin = ""
DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE)
DIM negativeFlg = IIF(dec < 0, TRUE, FALSE)
dec = ABS(dec)
DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
REPEAT
bin = (integer MOD 2) + bin
integer = INT(integer / 2)
UNTIL integer = 0
IFB decimalFlg THEN
bin = bin + "."
DIM loop = 0
REPEAT
loop = loop + 1
decimal = decimal * 2
bin = bin + IIF(decimal >= 1, "1", "0")
IF decimal > 1 THEN decimal = decimal - 1
UNTIL decimal = 1 OR loop >= 64
WHILE loop MOD 4 <> 0
loop = loop + 1
bin = bin + "0"
WEND
ENDIF
IFB VARTYPE(digits) = VAR_BOOLEAN THEN
bin = strPad(bin, CEIL(LENGTH(REPLACE(bin, ".", "")) / 8) * 8, "0", LEFT)
ELSE
bin = strPad(bin, digits, "0", LEFT)
ENDIF
IFB negativeFlg THEN
DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
DIM lsb = IIF(decimalFlg , POS(".", bin) - LENGTH(bin), 0)
DIM a = binToDec(bin, FALSE)
DIM b = POWER(2, msb) - 1
FOR i = -1 TO lsb STEP -1
b = b + POWER(2, i)
NEXT
dec = bitXor(a, b) + POWER(2, lsb)
bin = decToBin(dec, signFlg, digits, recursive + 1)
ENDIF
IFB recursive = 1 THEN
DIM bit = COPY(bin, 1, 1)
DIM len = LENGTH(REPLACE(bin, ".", ""))
IF negativeFlg AND (bit = "0" OR len MOD 2 <> 0) THEN bin = strRepeat("1", IIF(len MOD 2 <> 0, 4, 8)) + bin
IF !negativeFlg AND signFlg AND (bit = "1" OR len MOD 8 <> 0) THEN bin = strRepeat("0", IIF(len MOD 8 <> 0, 4, 8)) + bin
ENDIF
RESULT = bin
FEND
//////////////////////////////////////////////////
// 【引数】
// expr : 評価する式
// truepart : 評価した式がTrueのときに返す値
// falsepart : 評価した式がFalseのときに返す値
// 【戻り値】
// truepart : 評価した式がTrueのとき、falsepart : 評価した式がFalseのとき
//////////////////////////////////////////////////
FUNCTION IIF(expr, truepart, falsepart)
IFB EVAL(expr) THEN
RESULT = truepart
ELSE
RESULT = falsepart
ENDIF
FEND
//////////////////////////////////////////////////
// 【引数】
// str : 文字列
// characters : 削除する文字、デフォルトでは制御文字を表すASCII文字コードの範囲(\x00..\x1F\x7F)が指定されています。文字の範囲を指定する場合は、開始文字..終了文字の形式で指定。
// 【戻り値】
// 左側の制御文字もしくは指定された文字が取り除かれた文字列
//////////////////////////////////////////////////
FUNCTION leftTrim(str, characters = "\x00..\x1F\x7F")
characters = REPLACE(characters, "-", "\-")
IF reTest(characters, "\\x[0-9A-Fa-f]{2}\.\.\\x[0-9A-Fa-f]{2}") THEN characters = REPLACE(characters, "..", "-")
RESULT = reReplace(str, "", "^[" + characters + "]+")
FEND
//////////////////////////////////////////////////
// 【引数】
// str1 : 置換される文字列
// str2 : 置換後の文字列
// Pattern : 置換する文字列のパターン
// IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse
// Global : 文字列全体を検索する場合はTrue、しない場合はFalse
// 【戻り値】
// 正規表現置換後の文字列
//////////////////////////////////////////////////
FUNCTION reReplace(str1, str2, Pattern, IgnoreCase = TRUE, Global = TRUE)
DIM re = CREATEOLEOBJ("VBScript.RegExp")
re.Pattern = Pattern
re.IgnoreCase = IgnoreCase
re.Global = Global
RESULT = re.Replace(str1, str2)
FEND
//////////////////////////////////////////////////
// 【引数】
// str : 正規表現による検索の対象となる文字列
// Pattern : 正規表現で使用するパターンを設定
// IgnoreCase : 大文字・小文字を区別しない場合はTrue、区別する場合はFalse
// Global : 文字列全体を検索する場合はTrue、しない場合はFalse
// 【戻り値】
// 正規表現にマッチするかどうかを示すブール値
//////////////////////////////////////////////////
FUNCTION reTest(str, Pattern, IgnoreCase = TRUE, Global = TRUE)
DIM re = CREATEOLEOBJ("VBScript.RegExp")
re.Pattern = Pattern
re.IgnoreCase = IgnoreCase
re.Global = Global
RESULT = re.Test(str)
FEND
//////////////////////////////////////////////////
// 【引数】
// num : 符号を求める数値
// 【戻り値】
// 1 : 正の数、0 : ゼロ、-1 : 負の数、ERR_VALUE : それ以外
//////////////////////////////////////////////////
FUNCTION sign(num)
SELECT TRUE
CASE !CHKNUM(num)
RESULT = ERR_VALUE
CASE num > 0
RESULT = 1
CASE num = 0
RESULT = 0
CASE num < 0
RESULT = -1
SELEND
FEND
//////////////////////////////////////////////////
// 【引数】
// input : 入力文字列
// length : 埋めたあとの長さ
// str : 埋める文字
// type : 埋める方向
// 【戻り値】
// 指定文字で埋めた文字列
//////////////////////////////////////////////////
FUNCTION strPad(input, length, str = " ", type = RIGHT)
DIM s = ""
SELECT type
CASE LEFT
FOR i = 1 TO CEIL((length - LENGTH(input)) / LENGTH(str))
s = s + str
NEXT
input = COPY(s, 1, length - LENGTH(input)) + input
CASE RIGHT
FOR i = 1 TO CEIL((length - LENGTH(input)) / LENGTH(str))
s = s + str
NEXT
input = input + COPY(s, 1, length - LENGTH(input))
SELEND
RESULT = input
FEND
//////////////////////////////////////////////////
// 【引数】
// inputs : 繰り返す文字列
// multiplier : inputsを繰り返す回数
// 【戻り値】
// inputsをmultiplier回を繰り返した文字列を返します
//////////////////////////////////////////////////
FUNCTION strRepeat(inputs, multiplier)
DIM res = ""
FOR n = 1 TO multiplier
res = res + inputs
NEXT
RESULT = res
FEND
使い方
単精度浮動小数点数の数値をIEEE754形式の2進数の文字列に変換
単精度浮動小数点数をIEEE754形式で表された2進数の文字列に変換します。結果は4バイト(32文字)で返されます。
PRINT IEEE754.singleToBin(1.3)
- 結果
00111111101001100110011001100110
倍精度浮動小数点数の数値をIEEE754形式の2進数の文字列に変換
倍精度浮動小数点数をIEEE754形式で表された2進数の文字列に変換します。結果は8バイト(64文字)で返されます。
PRINT IEEE754.doubleToBin(1.3)
- 結果
0011111111110100110011001100110011001100110011001100110011001100
IEEE754形式の2進数の文字列を単精度浮動小数点数の数値に変換
IEEE754形式で表された2進数の文字列を単精度浮動小数点数の数値に変換します。単精度は4バイトなので32文字で指定します。00111111101001100110011001100110は1.3を単精度浮動小数点数をIEEE754形式に変換した文字列です。1.3は2進数で表したときに無限小数となり丸め誤差が生じるため精度は落ちます。
PRINT IEEE754.binToSingle("00111111101001100110011001100110")
- 結果
1.29999995231628
IEEE754形式の2進数の文字列を倍精度浮動小数点数の数値に変換
IEEE754形式で表された2進数の文字列を倍精度浮動小数点数の数値に変換します。倍精度は8バイトなので64文字で指定します。
PRINT IEEE754.binToDouble("0011111111110100110011001100110011001100110011001100110011001100")
- 結果
1.3