Встроенное двоичное преобразование в Scheme / Lisp - PullRequest
2 голосов
/ 03 июля 2019

Есть ли в схеме встроенная функция преобразования двоичного числа в десятичное?

Я нашел встроенное преобразование number->string, которое может преобразовывать двоичный код в десятичную форму.

Однако, противоположный string->number не преобразует десятичные числа в двоичную строку, как я думал.

Есть ли встроенная функция или мы должны ее определить?

Ответы [ 4 ]

5 голосов
/ 03 июля 2019

Двоичные и десятичные представления чисел;Сами числа не являются двоичными или десятичными.

number->string преобразует число (например, двенадцать) в строку (например, "12"), выводя базовое представление числа 10 по умолчанию.
(Он не преобразуется из двоичного в десятичное - его имя описывает, что он делает.)

string->number преобразует из строки (например, «12») в число (например, двенадцать), интерпретируя строку какбазовое представление числа 10 по умолчанию.
(Имя этой функции также описывает, что она делает.)

Вы можете передать второй аргумент обеим функциям для другого базового представления (2,8,10).или 16).

Чтобы получить строку с двоичным представлением числа n, используйте (number->string n 2).
Чтобы получить число из строки s с ее двоичным представлением, используйте(string->number s 2).

Примеры:

> (number->string 120)
"120"
> (string->number "120")
120
> (number->string 120 2)
"1111000"
> (string->number "1111000" 2)
120
> (number->string 120 16)
"78"
> (string->number "78" 16)
120
4 голосов
/ 03 июля 2019

Функция string->number принимает необязательный параметр radix:

(string->number "1001" 2)
==> 9
1 голос
/ 04 июля 2019

Common Lisp

Как и в Scheme, у чисел также нет основ в Common Lisp, только их представления.

Визуализация числа в базе с использованием write-to-string:

(write-to-string 10 :base 2)
; ==> "1010"

Считывание числа, представленного в определенной базе, с использованием parse-integer:

(parse-integer "1010" :radix 2)
; ==> 10
; ==> 4 (index where the parser terminated)

(parse-integer "1010.1" :radix 2) 
; parse-integer: substring "1010.1" does not have integer syntax at position 4

(parse-integer "1010.1" :radix 2 :junk-allowed t) 
; ==> 10
; ==> 4 (index where the parser terminated)

В качестве альтернативы вы можете использовать считыватель / принтер, однако чтение работает, только если следующий токен не может быть интерпретирован как число с плавающей запятой:

(let ((*print-base* 2))
  (prin1-to-string 10))
; ==> "1010"

(let ((*read-base* 2)) 
  (read-from-string "1010"))
; ==> 10
; ==> 5

;; *read-base* ignored when interpreted as float
(let ((*read-base* 2)) 
  (read-from-string "1010.1"))
; ==> 1010.1 
; ==> 6

Я предполагаю, что глобальный *print-base* и *read-base* равны десяти.read-from-string не волнует, есть ли после номера мусор, поэтому он ведет себя как (parse-integer "1010" :radix 2 :junk-allowed t)

В качестве дополнительной информации о прочитанном базовом документе.Вы можете указать читателю литералы для оснований 2, 8 и 16 и произвольные, которые переопределяют динамическую настройку:

#b1010            ; ==> 10 (base 2)
#o1010            ; ==> 520 (base 8)
#x1010            ; ==> 4112 (base 16)
#3r1010           ; ==> 30 (base 3)
#36rToBeOrNotToBe ; ==> 140613689159812836698 (base 36)
0 голосов
/ 04 июля 2019

Этот код был написан в мит-схеме. В других версиях lisp со статической областью действия он также должен работать, и вы можете предоставить реализацию char->digit, если такая функция отсутствует.

(define string->number
  (lambda (ibase)
    (lambda (str)
      ((lambda (s) (s s (map (lambda (a) (char->digit a ibase)) (string->list str)) 0))
       (lambda (s input n)
         (if (null? input)
             n
             (s s (cdr input)
                (+ (car input) (* n ibase)))))))))

(define str.convert.base.16 (string->number 16))
(define str.convert.base.10 (string->number 10))
(define str.convert.base.2 (string->number 2))
(define str.convert.base.3 (string->number 3))

(str.convert.base.10 "1001")
(str.convert.base.2 "1001")
(str.convert.base.3 "1001")
(str.convert.base.16 "100")

вывод мит-схемы:

1] => (str.convert.base.10 "1001"); Значение: 1001

1] => (str.convert.base.2 "1001"); Значение: 9

1] => (str.convert.base.3 "1001"); Значение: 28

1] => (str.convert.base.16 "100"); Значение: 256

...