自己流で、任意の有理数を$n$進法$(n\leq36)$で表示出来るようになりました。
原理
下記のように、任意の有理数を$n$進法で表示します。
$$\frac{a}{b}=\pm{c}.{}d[{e}]$$
aは整数で、bは自然数です。
c,d,eは$n$進法表示となります。[e]は循環小数の部分となります。
10進法 | $n$進法 |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
5 | 5 |
6 | 6 |
7 | 7 |
8 | 8 |
9 | 9 |
10 | A |
11 | B |
12 | C |
13 | D |
14 | E |
15 | F |
16 | G |
17 | H |
18 | I |
19 | J |
20 | K |
21 | L |
22 | M |
23 | N |
24 | O |
25 | P |
26 | Q |
27 | R |
28 | S |
29 | T |
30 | U |
31 | V |
32 | W |
33 | X |
34 | Y |
35 | Z |
10進法
> mod_change(-100,7,10)
[1] "-14.[285714]"
$\frac{-100}{7}$の10進法表示:$-14.295714285714\cdots$
2進法
> mod_change(-100,7,2)
[1] "-1110.[010]"
$\frac{-100}{7}$の10進法表示:$-1110.010010\cdots$
7進法
> mod_change(-100,7,7)
[1] "-20.2"
$\frac{-100}{7}$の10進法表示:$-20.2$
12進法
> mod_change(-100, 7, 12)
[1] "-12.[35186A]"
$\frac{-100}{7}$の12進法表示:$-12.35186A35186A\cdots$
16進法
> mod_change(-100, 7, 16)
[1] "-E.[492]"
$\frac{-100}{7}$の16進法表示:$-E.492492\cdots$
35進法
> mod_change(-100, 7, 35)
[1] "-E.A"
$\frac{-100}{7}$の35進法表示:$-E.A$
code
mod_change.r
mod_change <- function(numerator, denominator, base) {
Num = c("0", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z")
Integer = NULL
Decimal = NULL
n_1 = floor( log( abs( numerator / denominator ) ) / log(base) )
tar_1 = abs(numerator)
tar_2 = abs(denominator)
while (n_1 >= 0) {
Int = trunc( tar_1 / ( base**n_1*tar_2 ) )
Integer = paste(Integer, Num[Int+1], sep = "")
tar_1 = tar_1 - Int*base**n_1*tar_2
n_1 = n_1 - 1
}
if ( is.null(Integer) == TRUE ) {
Integer = "0"
}
if ( tar_1 != 0 ) {
if ( (base**ceiling(log(tar_2) / log(base)) * tar_1)%%tar_2 == 0 ) {
while (tar_1 != 0) {
Int = trunc(tar_1*base/tar_2)
Decimal = paste(Decimal, Num[Int+1], sep = "")
tar_1 = tar_1*base - Int*tar_2
}
}
if ( (base**ceiling(log(tar_2) / log(base)) * tar_1)%%tar_2 != 0 ) {
n_2 = 0
while (n_2 >= 0) {
if ( base%%(2**(n_2+1)) != 0 | tar_2%%(2**(n_2+1)) != 0 ) {
break
}
else {
n_2 = n_2 + 1
}
}
if ( n_2 != 0 ) {
tar_3 = base / (2**n_2) * tar_1
tar_4 = tar_2 / (2**n_2)
}
if ( n_2 == 0 ) {
tar_3 = tar_1
tar_4 = tar_2
}
tar_5 = tar_3
while (tar_5 > 0) {
Int = trunc(tar_5*base/tar_4)
Decimal = paste(Decimal, Num[Int+1], sep = "")
tar_5 = tar_5*base - Int*tar_4
if ( Int > 0 & tar_5 == tar_3 ) {
break
}
}
Decimal = paste("[", Decimal, sep = "")
Decimal = paste(Decimal, "]", sep = "")
if ( n_2 != 0 ) {
for (i_2 in 1:n_2) {
Decimal = paste(0, Decimal, sep = "")
}
}
}
}
if ( is.null(Decimal) == FALSE ) {
ans = paste(Integer, ".", sep = "")
ans = paste(ans, Decimal, sep = "")
}
if ( is.null(Decimal) == TRUE ) {
ans = Integer
}
if ( numerator / denominator < 0 ) {
ans = paste("-", ans, sep = "")
}
return(ans)
}