jdgo12
jdgo12

Reputation: 59

Built in Binary Conversion in Scheme/Lisp

Is there a built in binary to decimal conversion function in Scheme?

I've found the built in number->string conversion which can convert binary to decimal form.

However, the opposite string->number doesn't convert decimals to binary string like I'd thought.

Is there a built in function or would we have to define it?

Upvotes: 3

Views: 2274

Answers (3)

Sylwester
Sylwester

Reputation: 48745

Common Lisp

As with Scheme, numbers does not have bases in Common Lisp as well, only their representations.

Visualizing a number in a base using write-to-string:

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

Reading a number represented in a certain base using 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)

Alternatively you can use the reader/printer, however reading only works if the next token cannot be interpreted as a float:

(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

I assume global *print-base* and *read-base* is both ten. read-from-string doesn't care if there is junk after the number so it behaves as (parse-integer "1010" :radix 2 :junk-allowed t)

As an added info on the read base doc. You can tell the reader for literals for base 2, 8 and 16 and arbitrary which overrides the dynamic setting:

#b1010            ; ==> 10 (base 2)
#o1010            ; ==> 520 (base 8)
#x1010            ; ==> 4112 (base 16)
#3r1010           ; ==> 30 (base 3)
#36rToBeOrNotToBe ; ==> 140613689159812836698 (base 36)

Upvotes: 2

molbdnilo
molbdnilo

Reputation: 66371

Binary and decimal are representations of numbers; numbers themselves are not binary or decimal.

number->string converts from a number (such as twelve) to a string (such as "12"), outputting the number's base 10 representation by default.
(It does not convert from binary to decimal - its name describes what it does.)

string->number converts from a string (such as "12") to a number (such as twelve), interpreting the string as the base 10 representation of a number by default.
(This function's name also describes what it does.)

You can pass a second argument to both functions for a different base representation (2,8,10, or 16).

To get a string with the binary representation of the number n, use (number->string n 2).
To get a number from a string s with its binary representation, use (string->number s 2).

Examples:

> (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

Upvotes: 5

6502
6502

Reputation: 114481

The string->number function accepts an optional radix parameter:

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

Upvotes: 6

Related Questions