16進数から10進数に変換します。$表記は小数には対応していないため、10進数表記の小数の値を変換するにはhexToDec関数 (自作関数)を使います。
- 構文
- $(16進数)
- 引数
- 戻り値
- 10進数に変換した値
16進数とは
16進数とは0〜9の10個の数字と、A〜Fの6個のアルファベット(小文字も可)の16種類の文字を使って数値を表現する方法です。
コンピュータの内部では電圧の高低を1と0(スイッチのON/OFF)に対応付けた2進数であらゆる情報を表しています。そのためコンピュータにとって2進数が便利なのですが、2進数は桁が大きくなりすぎるため人間にとっては扱いづらい表現です。16進数だと1桁が4bitとビット数自体が\(2^{n}\)という形式になり便利なため、コンピュータで数値を扱うときには16進数がよく使われます。例えば、Web開発でカラーコードは#(シャープ)の後に数字6桁で#FF5733、文字コードは0x41のような16進数で表現されます。
10進数では一つの桁において0~9の10種類の文字を扱うことができるのに対し、16進数では0、1、2、3、4、5、6、7、8、9、A、B、C、 D、E、Fの16種類の文字を扱うことができます。
1から9までは10進数と同じ数値ですが、AからFは10から15に対応しています。
10進数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
16進数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 |
10進数では0,1,2,…,7,8,9と1桁で表現できる上限まで来ると10と桁が増えるように、16進数も0,1,2,…,D,E,Fの次は10と桁が上がります。このとき10はジュウではなく、イチゼロと読みます。
また10進数と16進数など複数の基数表記がある場合、例えば10が10進数のジュウなのか16進数のイチゼロなのかの区別がつきません。そのため以下の表に示すような接頭辞・接尾辞のいずれかをつけることで区別します。基数とは位取り記数法で数値を書き記す際に各桁の重み付けの基本となる数のことで10進数では10、16進数では16です
進数 | 2進数 | 8進数 | 10進数 | 16進数 |
---|---|---|---|---|
接頭辞 | 0b | 0oもしくは0 | 0d | 0x |
接尾辞 | b | o | d | h |
例えば0x10や10hというように書けば16進数の10、0d10や10dと書けば10進数の10というように何進数の表記なのかが明確になります。10進数のときは接頭辞・接尾辞を省略することもあります。
接頭辞・接尾辞のアルファベットはそれそれBinary(2進数)、Octal(8進数)、Decimal(10進数)、Hexadecimal(16進数)の頭文字から来ています。16進数の接頭辞のみheXadecimalと3文字目のxです。
ただし接尾辞のbやdは16進数の値との区別がつかなくなることがあるので、接頭辞を使うのをおすすめします。
右下に基数を小さく添え字として書く方法もありますが、この表記は数学で使われることがあってもプログラミングで使われることはあまりありません。
例えば\(1011_{2}\)は2進数の1011、\(13_{10}\)は10進数の13、\(5F_{16}\)は16進数の5Fのようになります。
使い方
16進数の0x5、0xA、0x1F、0xFFをそれぞれ10進数に変換します。
PRINT $5
PRINT $A
PRINT $1F
PRINT $FF
- 結果
5 10 31 255
表現できる範囲
$を使って表現できるのは、符号付き64bitの整数である-9,223,372,036,854,775,808~+9,223,372,036,854,775,807の範囲の数値です。(-922京3372兆0368億5477万5808〜922京3372兆0368億5477万5807)。
PRINT "最大値:" + $7FFFFFFFFFFFFFFF
PRINT "最小値:" + $8000000000000000
- 結果
最大値:9.22337203685478E18 最小値:-9.22337203685478E18
先頭の1bitは符号を表すために使われるので63bitが数値を表し、\(-2^{63}\)〜\(2^{63}-1\)の範囲となります。
符号ビット
最上位ビット が符号を表す符号ビットです。64bitなので16進数だと右から16桁目になります。2進数にしたとき0(16進数で0~7)であれば正数、1(16進数で8~F)であれば負数となります。
0x80は64bitで表記すると0x0000000000000080となり最上位ビットが0なので正数となります。
PRINT $80
PRINT $0000000000000080
- 結果
128 128
最上位ビットを省略すると0埋めされて正数になるので、負数を表現するには以下のように16桁で表現します。
PRINT $FFFFFFFFFFFFFFFF
PRINT $FFFFFFFFFFFFFFFE
PRINT $FFFFFFFFFFFFFFFD
- 結果
-1 -2 -3
計算
16進数同士
結果は10進数で返されます。
PRINT $F + $E // 15 + 14
PRINT $10 + $FFFFFFFFFFFFFFFA // 16 + (-6)
- 結果
29 10
16進数と10進数
16進数と10進数の値が混在していても、計算することができます。こちらも結果は10進数で返ります。
PRINT $F3 + 150 // 243 + 150
- 結果
393
16進数に変換するにはFORMAT関数 (スクリプト関数)を使います。第1引数に16進数に変換する値、第3引数に-1を指定します。
DIM dec = $F3 + 150
PRINT FORMAT(dec,, -1)
- 結果
189
decToHex関数 (自作関数)でも16進数に変換できます。最上位ビットで符号の判断をしているので先頭に0が入ることがあります。
PRINT decToHex($F3+150)
//////////////////////////////////////////////////
// 【引数】
// 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
//////////////////////////////////////////////////
// 【引数】
// dec : 10進数
// signFlg : 符号付きならばTrue
// recursive : 再帰処理の深さ。処理する際に必要なだけで指定する必要はありません。
// 【戻り値】
// 16進数に変換した値
//////////////////////////////////////////////////
FUNCTION decToHex(dec, signFlg = TRUE, recursive = 1)
DIM hex = ""
DIM array[] = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"
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
hex = array[integer MOD 16] + hex
integer = INT(integer / 16)
UNTIL integer = 0
IFB decimalFlg THEN
hex = hex + "."
DIM loop = 0
REPEAT
loop = loop + 1
decimal = decimal * 16
hex = hex + array[decimal]
offset = POWER(10, LENGTH(decimal) - POS(".", decimal))
decimal = (decimal * offset - INT(decimal) * offset) / offset
UNTIL decimal = 0 OR loop >= 4
ENDIF
DIM bin = hexToBin(hex)
DIM keta = LENGTH(bin)
IFB keta < 8 THEN
bin = strPad(bin, decimalFlg + 8, "0", LEFT)
ELSEIF keta < 16 THEN
bin = strPad(bin, decimalFlg + 16, "0", LEFT)
ELSEIF keta < 24 THEN
bin = strPad(bin, decimalFlg + 24, "0", LEFT)
ELSEIF keta < 32 THEN
bin = strPad(bin, decimalFlg + 32, "0", LEFT)
ELSE
bin = strPad(bin, decimalFlg + 64, "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 = hexToDec(hex, 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)
hex = decToHex(dec, signFlg, recursive + 1)
ENDIF
IFB recursive = 1 THEN
DIM bit = COPY(hexToBin(COPY(hex, 1, 1)), 1, 1)
DIM len = LENGTH(REPLACE(hex, ".", ""))
IF negativeFlg AND (bit = "0" OR len MOD 2 <> 0) THEN hex = strRepeat("F", IIF(len MOD 2 <> 0, 1, 2)) + hex
IF !negativeFlg AND signFlg AND (bit = "1" OR len MOD 2 <> 0) THEN hex = strRepeat("0", IIF(len MOD 2 <> 0, 1, 2)) + hex
ENDIF
RESULT = hex
FEND
//////////////////////////////////////////////////
// 【引数】
// hex : 16進数
// 【戻り値】
// 2進数に変換した値
//////////////////////////////////////////////////
FUNCTION hexToBin(hex)
HASHTBL hb
hb["0"] = "0000"; hb["1"] = "0001"; hb["2"] = "0010"; hb["3"] = "0011";
hb["4"] = "0100"; hb["5"] = "0101"; hb["6"] = "0110"; hb["7"] = "0111";
hb["8"] = "1000"; hb["9"] = "1001"; hb["A"] = "1010"; hb["B"] = "1011";
hb["C"] = "1100"; hb["D"] = "1101"; hb["E"] = "1110"; hb["F"] = "1111";
DIM bin = ""
IFB POS(".", hex) <> 0 THEN
FOR i = 1 TO LENGTH(hex)
DIM str = COPY(hex, i, 1)
IF str = "." THEN bin = bin + "."
bin = bin + hb[str]
NEXT
ELSE
FOR i = 1 TO LENGTH(hex)
bin = bin + hb[COPY(hex, i, 1)]
NEXT
ENDIF
RESULT = bin
FEND
//////////////////////////////////////////////////
// 【引数】
// hex : 16進数
// signFlg : 符号付きならばTrue
// 【戻り値】
// 10進数に変換した値
//////////////////////////////////////////////////
FUNCTION hexToDec(hex, signFlg = TRUE)
hex = STRCONV(hex, SC_UPPERCASE)
DIM dec = 0
DIM decimalFlg = IIF(POS(".", hex) <> 0, TRUE, FALSE)
hex = IIF(LENGTH(REPLACE(hex,".", "" )) MOD 2 <> 0, "0", "") + hex
DIM negativeFlg = IIF(COPY(hexToBin(hex), 1, 1) = "1", TRUE, FALSE)
DIM sign = 1
IF negativeFlg AND signFlg THEN sign = -1
IFB negativeFlg AND signFlg THEN
DIM bin = hexToBin(hex)
DIM msb = IIF(decimalFlg, POS(".", bin) - 1, LENGTH(bin))
DIM lsb = IIF(decimalFlg, POS(".", bin) - LENGTH(bin), 0)
DIM a = hexToDec(hex, FALSE)
DIM b = POWER(2, msb) - 1
FOR i = -1 TO lsb STEP -1
b = b + POWER(2, i)
NEXT
DIM dec2 = bitXor(a, b) + POWER(2, lsb)
hex = decToHex(dec2)
ENDIF
integer = IIF(decimalFlg, COPY(hex, 1, POS(".", hex) - 1), hex)
decimal = IIF(decimalFlg, COPY(hex, POS(".", hex) + 1), "0")
FOR i = 1 TO LENGTH(integer)
s = COPY(hex, i, 1)
num = IIF(CHKNUM(s), s, ASC(s) - (ASC("A") - 10))
dec = dec + num * POWER(16, LENGTH(integer) - i)
NEXT
FOR i = 1 TO LENGTH(decimal)
s = COPY(decimal, i, 1)
num = IIF(CHKNUM(s), s, ASC(s) - (ASC("A") - 10))
dec = dec + num * POWER(16, -1 * i)
NEXT
RESULT = sign * dec
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
- 結果
0189
関連記事
- hexToDec関数 (自作関数)
- 16進数を10進数に変換します。10進数を16進数に変換するにはdecToHex関数を使います。
- decToHex関数 (自作関数)
- 10進数を16進数に変換します。16進数を10進数に変換するにはhexToDec関数を使います。
- binToHex関数 (自作関数)
- 2進数を16進数に変換します。16進数を2進数に変換するにはhexToBin関数を使います。
- hexToBin関数 (自作関数)
- 16進数を2進数に変換します。2進数を16進数に変換するにはbinToHex関数を使います。
- decToBin関数 (自作関数)
- 10進数を2進数に変換します。負数・小数の値にも対応しています。
- binToDec関数 (自作関数)
- 2進数を10進数に変換します。10進数を2進数に変換するにはdecToBin関数を使います。