Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

implementing duodecimal numbers

12 views
Skip to first unread message

sardath

unread,
Feb 19, 2010, 10:47:42 AM2/19/10
to
I am interested in being able to do duodecimal (radix 12) arithmetic. Is
there a way to have for duodecimals something like the #b, #o, #x etc
notations for binary, octal, hex respectively? Can I define my own sharp
notation for a radix of my own choice and make it understood by the
interpreter as a number? How?


William D Clinger

unread,
Feb 19, 2010, 11:33:59 AM2/19/10
to
sardath wrote:
> I am interested in being able to do duodecimal (radix 12) arithmetic.
> Is there a way to have for duodecimals something like the #b, #o, #x etc
> notations for binary, octal, hex respectively?

Yes, that is permitted by IEEE/ANSI/R5RS Scheme,
although implementations are not required to make
it easy for you.

That is *not* permitted by R6RS Scheme, but most
implementations of R6RS Scheme have added lexical
extensions anyway. (Most of those implementations
provide some way to disable their R6RS-conflicting
lexical extensions, but there is no portable way
to do that. The #!r6rs flag that was intended to
be used for that purpose has been given different
semantics by different implementations.)

> Can I define my own sharp notation for a radix of my own choice
> and make it understood by the interpreter as a number?

Possibly. That is up to the implementation you're
using.

It isn't really the interpreter that matters here,
but the read procedure called by the interpreter.
You can redefine the read procedure in any system
that implements the IEEE/ANSI/R5RS standards, but
redefining the read procedure will not affect the
behavior of any standard procedure. In IEEE/ANSI
Scheme, it may affect the behavior of load and the
behavior of read/eval/print loops, because those
are not standard procedures in IEEE/ANSI Scheme.

The semantics of R6RS Scheme effectively forbids
interactive read/eval/print loops, so any such REPL
provided by an implementation of the R6RS is already
nonstandard, which means no general statements can
be made about its behavior with respect to the read
and get-datum procedures.

> How?

You can define your own read procedure and make it
understand any notations you like.

Some implementations provide easier ways to alter
the behavior of the predefined read procedure, but
all such techniques are implementation-dependent.

Will

Pascal J. Bourguignon

unread,
Feb 19, 2010, 12:58:16 PM2/19/10
to
"sardath" <milongue...@yahoo.com> writes:

> I am interested in being able to do duodecimal (radix 12) arithmetic.

In arithmetic, the notion of base is irrelevant. duodecimal arithmetic,
or decimal arithmetic doesn't mean anything. Arithmetic is numbers and
functions of numbers, and numbers don't have bases.

"thirteen plus seven is twenty" has nothing to do with any kind of
representation such as stones, positionnal representations, binary,
decimal or duodecimal.


It happens that there are algorithms implementing algorithm that may use
data representations for numbers such as base representation, often base
2 in electronic computer because that leads to simplier circuits, or
base ten in brains because they're taught that way because we've got
usually ten digits in the hands. But this is not arithmetics, this is
algorithmics, and the advantage these complex algorithms may have over
simplier algoritms more directly based on the axiomatic of numbers is
that the former are in general faster than the later.


For example, here is an algorithm to add two natural numbers:

(define (add a b)
(if (eql? zero a)
b
(add (pred a) (succ b))))


given the axiomatic of natural numbers:

(define zero '())
(define (succ n) (cons '() n))


and the inverse of succ:

(define (pred n) (assert (not (eql? zero n))) (cdr n))


The above algorithm is much much simplier than the one implemented in
electronic processor to add two numbers, which is similar to the
following (with the addded restriction of modular arithmetic):

(define (add a b)
;; First complexity, this algorithms doesn't work in terms of
;; numbers, but in terms of the representation of these numbers.
;; You cannot understand it without knowing what representation
;; I used.
(if (null? a)
b
(cond
((zero-bit-p (car a))
(cons (car b) (add (cdr a) (cdr b))))
((zero-bit-p (cdr b))
(cons (car a) (add (cdr a) (cdr b))))
(t
(cons zero-bit (add one (add (cdr a) (cdr b))))))))

With:

(define zero-bit 'zero)
(define one-bit 'one)
(define zero (list zero-bit))
(define one (list one-bit))
(define (zero-bit-p bit) (eql? bit zero-bit))

(define succ (n) (add one n))


Of course, you could implement algorithms for the arithmetic operations
using duodecimal representations, but this would be rather pointless.


> Is there a way to have for duodecimals something like the #b, #o, #x etc
> notations for binary, octal, hex respectively?

Of course, you can define any data structure you want to represent any
kind of data. If you want to represent numbers as duodecimal strings of
digits, you can.

You must choose how to represent the digits, how the duodecimal
representation is structured, and implement the data structure. That
means, write functions to convert between this data structure and the
_numbers_.


For example, if we choose to represent numbers as strings of characters
in the set (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\A #\B), with the
most significant digit first, we could define our durdecimal
representation as:


(define (duodecimal-number->string n)
(if (= 0 n)
"0"
(list->string (reverse (duodecimal-number->digits n)))))

(define (duodecimal-number->digits n)
(let ((d (list-ref '(#\0 #\1 #\2 #\3 #\4 #\5
#\6 #\7 #\8 #\9 #\A #\B)
(modulo n 12)))
(r (truncate (/ n 12))))
(if (= 0 r)
(list d)
(cons d (duodecimal-number->digits r)))))

(define (duodecimal-string->number s)
(duodecimal-digits->number
(reverse
(map (lambda (d)
(position d '(#\0 #\1 #\2 #\3 #\4 #\5
#\6 #\7 #\8 #\9 #\A #\B)))
(string->list s)))))

(define (duodecimal-digits->number d)
(if (null? d)
0
(+ (car d) (* 12 (duodecimal-digits->number (cdr d))))))

(define (position item list)
(cond
((null? list) (error "Invalid digit"))
((eqv? item (car list)) 0)
(else (+ 1 (position item (cdr list))))))

(duodecimal-string->number "100") --> 144
(duodecimal-number->string 144) --> "100"


> Can I define my own sharp
> notation for a radix of my own choice and make it understood by the
> interpreter as a number? How?

Transforming #d100 to (duodecimal-string->number "100") or even 144 at
read time, is a question of syntax, and in Scheme, this is
implementation dependant.

(In Common Lisp, there's a standardized way to add a reader macro to be
able to do so, cf SET-DISPATCH-MACRO-CHARACTER).

--
__Pascal Bourguignon__

Rob Warnock

unread,
Feb 21, 2010, 8:48:36 PM2/21/10
to
Pascal J. Bourguignon <p...@informatimago.com> wrote:
+---------------

| "sardath" <milongue...@yahoo.com> writes:
| > I am interested in being able to do duodecimal (radix 12) arithmetic.
...

| > Can I define my own sharp
| > notation for a radix of my own choice and make it understood by the
| > interpreter as a number? How?
|
| Transforming #d100 to (duodecimal-string->number "100") or even 144 at
| read time, is a question of syntax, and in Scheme, this is
| implementation dependant.
|
| (In Common Lisp, there's a standardized way to add a reader macro to be
| able to do so, cf SET-DISPATCH-MACRO-CHARACTER).
+---------------

In fact (as Pascal knows, of course), in Common Lisp there's already
a standardized number reader syntax for base 12 or base 17 or any base
up to 36:

> (list #12r100 (1+ #12rbb) #17r100 #36rzz)

(144 144 289 1295)
>


-Rob

-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607

0 new messages