LoginSignup
0
0

More than 5 years have passed since last update.

有理数をn進法で表示

Posted at

自己流で、任意の有理数を$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)
}
0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0