在Scheme / Lisp中内置二进制转换

时间:2019-07-03 04:24:22

标签: scheme lisp

方案中是否有内置的二进制到十进制转换功能?

我发现内置select * from TableA left outer join (select * from TableB where TableB.Field2 = 'somevalue') as TableB on TableA.Field1 = TableB.Field1 转换可以将二进制转换为十进制形式。

但是,相反的number->string不会像我所想的那样将小数转换为二进制字符串。

有内置函数还是我们必须定义它?

4 个答案:

答案 0 :(得分:5)

二进制和十进制表示数字;数字本身不是二进制或十进制。

number->string从数字(例如12)转换为字符串(例如“ 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

答案 1 :(得分:4)

string->number函数接受可选的radix参数:

(string->number "1001" 2)
==> 9

答案 2 :(得分:1)

常见的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)

答案 3 :(得分:-2)

这段代码是用mit-scheme编写的。在其他具有静态作用域的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")

mit-scheme的输出:

  

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