decToBinデシマルトゥーバイナリー関数

本ページには広告が含まれています。

10進数を2進数に変換します。2進数を10進数に変換するにはbinToDec関数 (自作関数)を使います。

構文
  1. UString = decToBin( dec, signFlg, digits, recursive )
引数
dec 必須
10進数
signFlg 省略可
符号付きならばTrue
digits 省略可
桁数
recursive 省略可
再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
戻り値
2進数に変換した値

プログラム

UWSC
//////////////////////////////////////////////////
// 【引数】
//   dec : 10進数 
//   signFlg : 符号付きならばTrue 
//   digits : 桁数 
//   recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION decToBin(dec, signFlg = TRUE, digits = FALSE, recursive = 1)
	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 >= 16
		WHILE loop MOD 4 <> 0
			loop = loop + 1
			bin = bin + "0"
		WEND
	ENDIF
	WHILE LENGTH(REPLACE(bin, ".", "")) MOD 8 <> 0
		bin = "0" + bin
	WEND
	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)
		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 
// 【戻り値】
//   
//////////////////////////////////////////////////
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進数) 
// 【戻り値】
//   
//////////////////////////////////////////////////
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のときに返す値 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION IIF(expr, truepart, falsepart)
	IFB EVAL(expr) THEN
		RESULT = truepart
	ELSE
		RESULT = falsepart
	ENDIF
FEND

//////////////////////////////////////////////////
// 【引数】
//   num : 符号を求める数値 
// 【戻り値】
//   
//////////////////////////////////////////////////
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を繰り返す回数 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION strRepeat(inputs, multiplier)
	DIM res = ""
	FOR n = 1 TO multiplier
		res = res + inputs
	NEXT
	RESULT = res
FEND

解説

  1. 2行目
    UWSC
    	DIM bin = ""
    2進数に変換した値を代入しておく変数。
  2. 3行目
    UWSC
    	DIM decimalFlg = IIF(POS(".", dec) <> 0, TRUE, FALSE)
    decが小数ならばdecimalFlgにTrue、小数でなければFalseが代入されます。
  3. 4行目
    UWSC
    	DIM negativeFlg = IIF(dec < 0, TRUE, FALSE)
    decが負数ならばTrue、負数でなければFalseがnegativeFlg代入されます。
  4. 5行目
    UWSC
    	dec = ABS(dec)
    decの符号を外し、decに代入し直します。
  5. 6行目
    UWSC
    	DIM integer = IIF(decimalFlg, COPY(dec, 1, POS(".", dec) - 1), dec)
    decの整数部分(小数点より左側)をintegerに代入します。
  6. 7行目
    UWSC
    	DIM offset = POWER(10, LENGTH(dec) - POS(".", dec))
    コンピュータでは浮動小数点数型は2進数で管理されていて丸め誤差が発生する可能性があるので、整数に直してから計算するための値。1.5なら10(\(=10^{1}\))倍、2.25なら100(\(=10^{2}\))倍のように小数点以下の桁数から何倍すれば整数になるかを求めoffsetに代入します。以下のように単純に整数を切り捨てると誤差が発生する可能性があるのでダメ。
    UWSC
    DIM decimal = dec - INT(dec)
  7. 8行目
    UWSC
    	DIM decimal = IIF(decimalFlg, COPY(dec, POS(".", dec) + 1) / offset, 0)
    decの小数部分(小数点より右側)を取得しoffsetで割ることで小数部分の値を計算し、その値をdecimalに代入します。小数でなければ0を代入します。
  8. 9-12行目
    UWSC
    	REPEAT
    		bin = (integer MOD 2) + bin
    		integer = INT(integer / 2)
    	UNTIL integer = 0
    整数部分を2進数に変換します。integerを2で割っていき、その余りをbinの左側に結合していきます。integerに2で割った整数部分を代入し直し、integerが0になるまで続けます。これで整数部分の2進数の変換は完了します。
  9. 13,26行目
    UWSC
    	IFB decimalFlg THEN
    		…
    	ENDIF
    小数部分を2進数に変換する処理。
  10. 14行目
    UWSC
    		bin = bin + "."
    binの右側に小数点をつけます。
  11. 15行目
    UWSC
    		DIM loop = 0
    2進数に変換した際に無限小数(無限ループ)になる可能性があるので、途中で抜けるためのカウンター。
  12. 16,21行目
    UWSC
    		REPEAT
    			…
    		UNTIL decimal = 1 OR loop >= 16
    小数部分を2進数に変換します。decimalが1になるかloopが16以上になったらループを抜ける。2進数で小数点以下16桁より先は求めずに終了する。
  13. 17行目
    UWSC
    			loop = loop + 1
    小数点以下の何桁目の処理かを表すloopに1を加算。
  14. 18-19行目
    UWSC
    			decimal = decimal * 2
    			bin = bin + IIF(decimal >= 1, "1", "0")
    decimalに2倍した値を代入し、decimalが1以上ならばbinの右側に1、そうでなければ0を結合する。
  15. 20行目
    UWSC
    			IF decimal > 1 THEN decimal = decimal - 1
    decimalが1より大きければ1を引いた値を代入し直す。
  16. 22-25行目
    UWSC
    		WHILE loop MOD 4 <> 0
    			loop = loop + 1
    			bin = bin + "0"
    		WEND
    小数点以下の桁数が4の倍数(4,8,12,16)になるようにbinの右側に0を結合。
  17. 27-29行目
    UWSC
    	WHILE LENGTH(REPLACE(bin, ".", "")) MOD 8 <> 0
    		bin = "0" + bin
    	WEND
    binの小数点を除いた文字数を4で割った余りが0になるまで、binの左側に0を結合する。桁数が4の倍数(4,8,12,...)になるようにする。
  18. 30,40行目
    UWSC
    	IFB negativeFlg THEN
    		…
    	ENDIF
    decが負数のときの処理。ビットを反転させる処理を行っています。
  19. 31行目
    UWSC
    		DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
    最上位ビットを取得。小数ならばbinの小数点の左側の文字数、小数でなければ全体の文字数で最上位ビットを取得できます。
  20. 32行目
    UWSC
    		DIM lsb = IIF(decimalFlg , POS(".", bin) - LENGTH(bin), 0)
    最下位ビットを取得。小数ならばbinの全体の文字数から整数部分の文字数を引いた値、小数でなれれば0で最下位ビットを取得できます。値は0かマイナスの値です。
  21. 33-39行目
    UWSC
    		DIM a = binToDec(bin)
    		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)
    2の補数を求めます。2の補数は1の補数(すべてのビットを反転させた値)に最下位ビットを加えたものです。
  22. 33行目
    UWSC
    		DIM a = binToDec(bin)
    binを10進数に変換してaに代入します。
  23. 34-37行目
    UWSC
    		DIM b = POWER(2, msb) - 1
    		FOR i = -1 TO lsb STEP -1
    			b = b + POWER(2, i)
    		NEXT
    bに反転させるための値を代入します。\(2^{msb-1}\)が整数部分、FOR文が小数部分となります。この値は2進数に変換するとすべてのビットが1になっている状態です。
  24. 38行目
    UWSC
      		dec = bitXor(a, b) + POWER(2, lsb)
    abの排他的論理和を求め、最下位ビットを加えた値をdecに代入します。
  25. 39行目
    UWSC
     		bin = decToBin(dec, signFlg, digits, recursive + 1)
    decを2進数に変換します。

10進数を2進数に変換

10進数を2進数に変換

使い方

UWSC
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
結果
CSV
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進数に変換します。負数・小数の値にも対応しています。
binToHex関数 (自作関数)
2進数を16進数に変換します。負数・小数の値にも対応しています。
hexToBin関数 (自作関数)
16進数を2進数に変換します。負数・小数の値にも対応しています。
hexToDec関数 (自作関数)
16進数を10進数に変換します。負数・小数の値にも対応しています。
decToHex関数 (自作関数)
10進数を16進数に変換します。負数・小数の値にも対応しています。
radToDeg関数 (自作関数)
弧度法から度数法に変換します。
degToRad関数 (自作関数)
度数法から弧度法に変換します。
ARABIC関数 (自作関数)
ローマ数字アラビア数字に変換します。
ROMAN関数 (自作関数)
アラビア数字ローマ数字に変換します。
16進数