本ページには広告が含まれています。
10進数を2進数に変換します。2進数を10進数に変換するにはbinToDec関数 (自作関数)を使います。
- 構文
- UString = decToBin( dec, signFlg, digits, recursive )
- 引数
- dec 必須
- 10進数
- signFlg 省略可
- 符号付きならばTrueを指定
- digits 省略可
- 変換した2進数の桁数合わせを自動で行うかを示すブール値、もしくは桁数を表す数値(8,16,24,32,64のいずれか)を指定
- recursive 省略可
- 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
- 戻り値
- 2進数に変換した値
プログラム
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// 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
解説
- 10行目
- 2進数に変換した値を代入しておく変数。
DIM bin = ""
- 11行目
- decが小数ならばdecimalFlgにTrue、小数でなければFalseが代入されます。
DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE)
- 12行目
- decが負数ならばTrue、負数でなければFalseがnegativeFlg代入されます。
DIM negativeFlg = IIF(dec < 0, TRUE, FALSE)
- 13行目
- decの符号を外し、decに代入し直します。
dec = ABS(dec)
- 14行目
- decの整数部分(小数点より左側)をintegerに代入します。
DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
- 15行目
- コンピュータでは浮動小数点数型は2進数で管理されていて丸め誤差が発生する可能性があるので、整数に直してから計算するための値。1.5なら10(\(=10^{1}\))倍、2.25なら100(\(=10^{2}\))倍のように小数点以下の桁数から何倍すれば整数になるかを求めoffsetに代入します。以下のように単純に整数を切り捨てると誤差が発生する可能性があるのでダメ。
DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
DIM decimal = dec - INT(dec)
- 16行目
- decの小数部分(小数点より右側)を取得しoffsetで割ることで小数部分の値を計算し、その値をdecimalに代入します。小数でなければ0を代入します。
DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
- 17-20行目
- 整数部分を2進数に変換します。integerを2で割っていき、その余りをbinの左側に結合していきます。integerに2で割った整数部分を代入し直し、integerが0になるまで続けます。これで整数部分の2進数の変換は完了します。
REPEAT bin = (integer MOD 2) + bin integer = INT(integer / 2) UNTIL integer = 0
- 21,34行目
- 小数部分を2進数に変換する処理。
IFB decimalFlg THEN … ENDIF
- 22行目
- binの右側に小数点をつけます。
bin = bin + "."
- 23行目
- 2進数に変換した際に無限小数(無限ループ)になる可能性があるので、途中で抜けるためのカウンター。
DIM loop = 0
- 24,29行目
- 小数部分を2進数に変換します。decimalが1になるかloopが16以上になったらループを抜ける。2進数で小数点以下16桁より先は求めずに終了する。
REPEAT … UNTIL decimal = 1 OR loop >= 64
- 25行目
- 小数点以下の何桁目の処理かを表すloopに1を加算。
loop = loop + 1
- 26-27行目
- decimalに2倍した値を代入し、decimalが1以上ならばbinの右側に1、そうでなければ0を結合する。
decimal = decimal * 2 bin = bin + IIF(decimal >= 1, "1", "0")
- 28行目
- decimalが1より大きければ1を引いた値を代入し直す。
IF decimal > 1 THEN decimal = decimal - 1
- 30-33行目
- 小数点以下の桁数が4の倍数(4,8,12,16)になるようにbinの右側に0を結合。
WHILE loop MOD 4 <> 0 loop = loop + 1 bin = bin + "0" WEND
- 35-39行目
- (binの小数点を除いた文字数を4で割った余りが0になるまで、binの左側に0を結合する。桁数が4の倍数(4,8,12,...)になるようにする。)
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
- 40,50行目
- decが負数のときの処理。ビットを反転させる処理を行っています。
IFB negativeFlg THEN … ENDIF
- 41行目
- 最上位ビットを取得。小数ならばbinの小数点の左側の文字数、小数でなければ全体の文字数で最上位ビットを取得できます。
DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
- 42行目
- 最下位ビットを取得。小数ならばbinの全体の文字数から整数部分の文字数を引いた値、小数でなれれば0で最下位ビットを取得できます。値は0かマイナスの値です。
DIM lsb = IIF(decimalFlg , POS(".", bin) - LENGTH(bin), 0)
- 43-49行目
- 2の補数を求めます。2の補数は1の補数(すべてのビットを反転させた値)に最下位ビットを加えたものです。
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)
- 43行目
- binを10進数に変換してaに代入します。
DIM a = binToDec(bin, FALSE)
- 44-47行目
- bに反転させるための値を代入します。\(2^{msb-1}\)が整数部分、FOR文が小数部分となります。この値は2進数に変換するとすべてのビットが1になっている状態です。
DIM b = POWER(2, msb) - 1 FOR i = -1 TO lsb STEP -1 b = b + POWER(2, i) NEXT
- 48行目
- aとbの排他的論理和を求め、最下位ビットを加えた値をdecに代入します。
dec = bitXor(a, b) + POWER(2, lsb)
- 49行目
- decを2進数に変換します。
bin = decToBin(dec, signFlg, digits, recursive + 1)
- 57行目
- binを戻り値として返す。
RESULT = bin
10進数を2進数に変換
使い方
DIM array[] = 15, 16, 5489, 187, -15, -478, -84568, -1234, 15.5, 547.125, -257.03125, -12564.112
FOR item IN array
PRINT item + "," + decToBin(item)
NEXT
- 結果
15, 00001111 16, 00010000 5489, 0001010101110001 187, 0000000010111011 -15, 11110001 -478, 1111111000100010 -84568, 111111101011010110101000 -1234, 1111101100101110 15.5, 000000001111.1000 547.125, 001000100011.0010 -257.03125, 1111111011111110.11111000 -12564.112, 1100111011101011.1110001101010101
関連記事
- binToDec関数 (自作関数)
- 2進数を10進数に変換します。10進数を2進数に変換するにはdecToBin関数を使います。
- binToHex関数 (自作関数)
- 2進数を16進数に変換します。16進数を2進数に変換するにはhexToBin関数を使います。
- hexToBin関数 (自作関数)
- 16進数を2進数に変換します。2進数を16進数に変換するにはbinToHex関数を使います。
- hexToDec関数 (自作関数)
- 16進数を10進数に変換します。10進数を16進数に変換するにはdecToHex関数を使います。
- decToHex関数 (自作関数)
- 10進数を16進数に変換します。16進数を10進数に変換するにはhexToDec関数を使います。
- radToDeg関数 (自作関数)
- 弧度法(Radian)を度数法(Degree)に変換します。度数法を弧度法に変換するにはDegToRad関数を使います。
- degToRad関数 (自作関数)
- 度数法(Degree)を弧度法(Radian)に変換します。弧度法を度数法に変換するにはRadToDeg関数を使います。
- ARABIC関数 (自作関数)
- ARABIC関数は、ローマ数字をアラビア数字に変換する関数です。アラビア数字をローマ数字に変換するには、ROMAN関数を使います。
- ROMAN関数 (自作関数)
- ROMAN関数は、アラビア数字をローマ数字に変換する関数です。ローマ数字をアラビア数字に変換するには、ARABIC関数を使います。
- 16進数