Discussion:
ibase and obase
van Nek
2006-06-18 18:54:20 UTC
Permalink
Hello,

is this a bug or intended?

(%i1) [ibase:10,obase:16]$
(%i2) 100;
(%o2) 64
(%i3) 111;
(%o3) 6F
(%i4) [ibase:16,obase:10]$
(%i5) 64;
(%o5) 100
(%i6) 6F;Incorrect syntax: F is not an infix operator
6F;
^
(%i6) 6E;
Incomplete number. Missing exponent?
-- an error. Quitting. To debug this try debugmode(true);

Documentation:
When ibase is greater than 10, the numerals comprise the decimal numerals 0 through 9
plus capital letters of the alphabet A, B, C, ..., as needed.

This tells me that 6F and 6E should work, or do I misunderstand the documentation?

Volker
Richard Fateman
2006-06-18 19:01:44 UTC
Permalink
6E looks like a floating point number. Like 6.0e1 is 60.0.



It is probably unintended. I think the way to fix it is to simply

forbid ibase to be set to more than decimal 10.



_____

From: maxima-***@math.utexas.edu [mailto:maxima-***@math.utexas.edu] On
Behalf Of van Nek
Sent: Sunday, June 18, 2006 11:54 AM
To: ***@math.utexas.edu
Subject: [Maxima] ibase and obase



Hello,



is this a bug or intended?



(%i1) [ibase:10,obase:16]$

(%i2) 100;

(%o2) 64

(%i3) 111;

(%o3) 6F

(%i4) [ibase:16,obase:10]$

(%i5) 64;

(%o5) 100

(%i6) 6F;Incorrect syntax: F is not an infix operator

6F;

^

(%i6) 6E;

Incomplete number. Missing exponent?

-- an error. Quitting. To debug this try debugmode(true);



Documentation:

When ibase is greater than 10, the numerals comprise the decimal numerals 0
through 9 plus capital letters of the alphabet A, B, C, ..., as needed.



This tells me that 6F and 6E should work, or do I misunderstand the
documentation?



Volker
Robert Dodier
2006-06-18 22:46:07 UTC
Permalink
Post by van Nek
(%i6) 6F;Incorrect syntax: F is not an infix operator
6F;
^
(%i6) 6E;
Incomplete number. Missing exponent?
This tells me that 6F and 6E should work, or do I misunderstand the documentation?
It should work. The observed behavior is a bug.

Maxima's parser calls common-lisp:read-from-string to convert strings
like "1234" into integers. read-from-string is happy enough with
stuff like 6e but the Maxima parser barfs before it gets to read-from-string.

A solution is to make the Maxima parser happy with 6e, etc.
I don't think any revision of stuff downstream of that is needed.
Probably there would need to be some special notation to help
the parser distinguish integers from floats and symbols.
I can't think of anything at the moment.

Robert Dodier
Richard Fateman
2006-06-19 02:29:25 UTC
Permalink
Not a solution.

6E1 is 60.0

If ibase is (decimal) 15 or more, then 6E1 is also an
integer.

Also many variable names are ambiguously either names or numbers.
For example, e^f could be 14^15 in decimal.

It seems to me then, that language acceptable to Maxima must either be
altered to be unambiguous, or we restrict ibase.
Commercial Macsyma says this about ibase:

"

The base for inputting numbers. The value assigned to this variable
must be an integer between 2 and 36 inclusive. If IBASE is assigned a
value greater than 10, Macsyma provides no way to specify digits above
9. This does not affect floating-point numbers or bigfloats.

"




-----Original Message-----
From: maxima-***@math.utexas.edu [mailto:maxima-***@math.utexas.edu] On
Behalf Of Robert Dodier
Sent: Sunday, June 18, 2006 3:46 PM
To: van Nek
Cc: ***@math.utexas.edu
Subject: Re: [Maxima] ibase and obase
Post by van Nek
(%i6) 6F;Incorrect syntax: F is not an infix operator
6F;
^
(%i6) 6E;
Incomplete number. Missing exponent?
This tells me that 6F and 6E should work, or do I misunderstand the documentation?
It should work. The observed behavior is a bug.

Maxima's parser calls common-lisp:read-from-string to convert strings
like "1234" into integers. read-from-string is happy enough with
stuff like 6e but the Maxima parser barfs before it gets to
read-from-string.

A solution is to make the Maxima parser happy with 6e, etc.
I don't think any revision of stuff downstream of that is needed.
Probably there would need to be some special notation to help
the parser distinguish integers from floats and symbols.
I can't think of anything at the moment.

Robert Dodier
Robert Dodier
2006-06-19 04:20:30 UTC
Permalink
Post by Richard Fateman
It seems to me then, that language acceptable to Maxima must either be
altered to be unambiguous, or we restrict ibase.
Well, I don't know about that. Maxima already has a mechanism to
force the interpretation of an input as a symbol rather than an integer
(namely a leading backslash). Floats can be distinguished by
putting an explicit decimal point. Dunno about bigfloats.

Even if disambiguation is imperfect, being able to input in bases > 10
can still be useful in some circumstances, and therefore we ought to allow it.
For example, keys, signatures, etc for encryption are large integers which
are often represented in base 16. Since Maxima is already a pleasant
environment for working with big integers, it would be very nice to allow
base 16 input.

For the record here is a reimplementation of ascii-numberp
and some examples. Note the use of the trailing decimal point
to indicate an integer in base 10; this is a useful Lisp-ism inherited
by Maxima.

(defun ascii-numberp (putative-digit)
(and
(characterp putative-digit)
(find
(char-downcase putative-digit)
(subseq "0123456789abcdefghijklmnopqrstuvwxyz" 0 *read-base*))))


(%i5) ibase : 16;
(%o5) 16
(%i6) 100;
(%o6) 256
(%i7) ddb36d4874312374824c36336a7aeaff;
(%o7) 294691024729178307052832132857585134335
(%i8) ff00;
(%o8) 65280
(%i9) \ff00;
(%o9) ff00
(%i10) symbolp (%);
(%o10) true
(%i11) obase : 16. ;
(%o11) 10
(%i12) %o7;
(%o12) DDB36D4874312374824C36336A7AEAFF
(%i13) integerp (%);
(%o13) true
(%i14) foo;
Incorrect syntax: oo is not an infix operator
foo;
^
(%i14) \foo;
(%o14) foo
(%i15) %o7 ^ 2;
(%o15) BFFF48711A961B6226778636F05D6A2BFE3E28E79B6A7BFDF7CF3B39FEC32A01
(%i16) ibase : 10. ;
(%o16) A
(%i17) %o15;
(%o17) BFFF48711A961B6226778636F05D6A2BFE3E28E79B6A7BFDF7CF3B39FEC32A01
(%i18) obase : 10. ;
(%o18) 10
(%i19) %o15;
(%o19)
86842800055933180499672050140245958196094653067807268462301167072379995892225

FWIW
Robert Dodier
Richard Fateman
2006-06-19 04:54:46 UTC
Permalink
It seems you are proposing to change the language for floats to require an
explicit decimal point. This is one option, but not my favorite. I don't
care for the backslash-- it is too easy to forget, and it doesn't always
lead to an error message.
Also it is not backward compatible.

I think that input of hexadecimal could be done by just adding a function.
For example, read_from_string("ff00",16).

This is not an important issue if the program works OK as long as ibase is
set to some normal value.

RJF
Robert Dodier
2006-06-19 14:18:58 UTC
Permalink
Post by Richard Fateman
It seems you are proposing to change the language
for floats to require an explicit decimal point. This is
one option, but not my favorite. I don't care for the
backslash-- it is too easy to forget, and it doesn't
always lead to an error message.
Also it is not backward compatible.
Explicit disambiguation on the part of the user is a hassle,
but it's needed only when ibase makes some inputs
ambiguous. If I set ibase so that a through z look like
digits, I'll have to write \load, \print, 1.0e0, etc, but
that's a problem of my own creation; Maxima is just
doing its best to follow instructions.

Maxima inherits symbol/number ambiguity from Lisp,
where it doesn't appear to have caused any damage.
E.g. (setq *read-base* 36) '(now is the time for all good men)
=> (30704 676 38210 1377158 20331 13737 778477 29039)
Post by Richard Fateman
This is not an important issue if the program works OK as
long as ibase is set to some normal value.
This is a key point. The proposed revision of ascii-numberp
changes the interpretation of some input tokens only if ibase != 10.

Robert Dodier
Stavros Macrakis
2006-06-19 13:50:01 UTC
Permalink
Input in bases > 10 is occasionally useful, I agree. But only occasionally.
It would be a bad idea to break longstanding, useful syntax such as ordinary
variable names (a, b, c), floating-point numbers (2e3 = 2000), initial
zeroes (00777 = 777) and the dot operator (non-commutative multiplication) (
aa.bb = "."(aa,bb) ) to accommodate large bases.

What's more, using global variables like ibase/obase means that every
loadfile etc. needs to be careful. This is very occasionally useful, but
perhaps even better would be a syntax that explicitly specifies the base, so
that input and output are unambiguous.

Consider specifying "A0" in base 12. Here are some possible syntaxes that
are consistent with current syntax (I think):

//12/A0/ -- do any standard extension packages use the
operator // ?
"A0"[12] -- currently treats as a subscripted variable,
but we might
want "abc"[2] == "b" at some
point...
#(A0,12)
#A0#12
#12#A0#

All pretty ugly, better solutions welcome....

Or maybe sticking with the functional solution

base("A0",12)

is the simplest....

-s
Robert Dodier
2006-06-19 14:49:50 UTC
Permalink
Post by Stavros Macrakis
Input in bases > 10 is occasionally useful, I agree.
But only occasionally.
Yes, and on those rare occasions, I want to get some
useful behavior, instead of "Why doesn't this work?"
Post by Stavros Macrakis
It would be a bad idea to break longstanding, useful syntax
such as ordinary variable names (a, b, c), floating-point numbers
(2e3 = 2000), initial zeroes (00777 = 777) and the dot operator
(non-commutative multiplication) (aa.bb = "."(aa,bb) ) to
accommodate large bases.
If I tell Maxima "Treat everything from a to z as a digit"
the best I can hope for is that a, b, c, 2e3, etc become integers.
If that's not what I want, then I won't change ibase.

Common Lisp allows this same ambiguity, and somehow
it staggers ahead unimpeded.
Post by Stavros Macrakis
What's more, using global variables like ibase/obase means
that every loadfile etc. needs to be careful.
This is beside the point -- ibase and obase already exist
and already have the potential to goof up any/every bit
of code by changing the global environment, just like any
other global variable.
Post by Stavros Macrakis
This is very occasionally useful,
Yes, so one would only change ibase if they thought it useful.
Post by Stavros Macrakis
but perhaps even better would be a syntax that explicitly
specifies the base, so that input and output are unambiguous.
I'm not opposed to that, although I wonder what is an acceptable notation.
Post by Stavros Macrakis
Or maybe sticking with the functional solution
base("A0",12)
base(A0, 12) is OK by me (I'd rather get rid of the quote marks).
The hard part of this, at present, is persuading the input
scanner to let through stuff like 3A0 -- at present this triggers
"A is not an infix operator" or some such.
base(\3A0, 12) would work. Well, it's ugly.

FWIW
Robert Dodier
Raymond Toy
2006-06-19 20:20:06 UTC
Permalink
Robert> If I tell Maxima "Treat everything from a to z as a digit"
Robert> the best I can hope for is that a, b, c, 2e3, etc become integers.
Robert> If that's not what I want, then I won't change ibase.

Robert> Common Lisp allows this same ambiguity, and somehow
Robert> it staggers ahead unimpeded.

I assume this is so because most people don't change the base, but use
the special reader syntax to input the numbers, like #xabc, #o123,
#b10101, etc. I certainly have had no need for numbers in other
bases.

And after looking at some other Lisp code where the default base was
8, it's no fun trying to understand what is happening if you didn't
know the base was set to 8.

Ray
laurent couraud
2006-06-19 20:28:08 UTC
Permalink
Is it really necessary to specify the base in the input?
Because we have ibase. I think you don't have the need to specify it.

Consider :

(%i1) prefix("&");
(%i2) "&"(x):=x;
(%i3) ibase : 10;
(%i4) &549;
(%o4) 549
(%i5) ibase : 16;
(%i6) &ffbc;
(%o6) ffbc

No?
-----Message d'origine-----
Envoyé : lundi 19 juin 2006 16:50
Objet : Re: [Maxima] ibase and obase
Post by Stavros Macrakis
Input in bases > 10 is occasionally useful, I agree.
But only occasionally.
Yes, and on those rare occasions, I want to get some
useful behavior, instead of "Why doesn't this work?"
Post by Stavros Macrakis
It would be a bad idea to break longstanding, useful syntax such as
ordinary variable names (a, b, c), floating-point numbers (2e3 =
2000), initial zeroes (00777 = 777) and the dot operator
(non-commutative multiplication) (aa.bb = "."(aa,bb) ) to
accommodate
Post by Stavros Macrakis
large bases.
If I tell Maxima "Treat everything from a to z as a digit"
the best I can hope for is that a, b, c, 2e3, etc become
integers. If that's not what I want, then I won't change ibase.
Common Lisp allows this same ambiguity, and somehow
it staggers ahead unimpeded.
Post by Stavros Macrakis
What's more, using global variables like ibase/obase means
that every
Post by Stavros Macrakis
loadfile etc. needs to be careful.
This is beside the point -- ibase and obase already exist
and already have the potential to goof up any/every bit
of code by changing the global environment, just like any
other global variable.
Post by Stavros Macrakis
This is very occasionally useful,
Yes, so one would only change ibase if they thought it useful.
Post by Stavros Macrakis
but perhaps even better would be a syntax that explicitly specifies
the base, so that input and output are unambiguous.
I'm not opposed to that, although I wonder what is an
acceptable notation.
Post by Stavros Macrakis
Or maybe sticking with the functional solution
base("A0",12)
base(A0, 12) is OK by me (I'd rather get rid of the quote
marks). The hard part of this, at present, is persuading the
input scanner to let through stuff like 3A0 -- at present
this triggers "A is not an infix operator" or some such.
base(\3A0, 12) would work. Well, it's ugly.
FWIW
Robert Dodier
_______________________________________________
Maxima mailing list
http://www.math.utexas.edu/mailman/listinfo/maxima
van Nek
2006-06-20 15:22:40 UTC
Permalink
Post by Robert Dodier
For the record here is a reimplementation of ascii-numberp
and some examples. Note the use of the trailing decimal point
to indicate an integer in base 10; this is a useful Lisp-ism inherited
by Maxima.
(defun ascii-numberp (putative-digit)
(and
(characterp putative-digit)
(find
(char-downcase putative-digit)
(subseq "0123456789abcdefghijklmnopqrstuvwxyz" 0 *read-base*))))
Hi Robert,

I have loaded this code and tried it out.

(%i2) block( [ibase:16], a );
(%o2) a
(%i3) block( ibase:16, a );
(%o3) a
(%i4) a;
(%o4) 10

An assignment to ibase in a block doesn't have any consequence inside the block itself.
Does it make sense then, if this only works in top level?

Maybe one could think about implementing bytestrings.

Volker
Robert Dodier
2006-06-20 15:39:23 UTC
Permalink
Volker,
Post by van Nek
(%i2) block( [ibase:16], a );
(%o2) a
(%i3) block( ibase:16, a );
(%o3) a
(%i4) a;
(%o4) 10
An assignment to ibase in a block doesn't have any consequence inside the block itself.
Does it make sense then, if this only works in top level?
That is to be expected. Maxima parses the entire input expression
before evaluating it. So in block([ibase : 16], a) , a is read with the
value of ibase *before* 16 is assigned.
Post by van Nek
Maybe one could think about implementing bytestrings.
Not sure what you mean here. Maybe you can expand on this point.

Robert
Richard Fateman
2006-06-20 15:51:46 UTC
Permalink
in the
Line %i2, below, the ibase is not set to 16 when the symbol "a" is read.
If you want to see the scope of ibase, you would have to do something like

Block([ibase:8], x:read()).

In this example, if you type 10; it will be read as octal.

RJF


-----Original Message-----
From: maxima-***@math.utexas.edu [mailto:maxima-***@math.utexas.edu] On
Behalf Of van Nek
Sent: Tuesday, June 20, 2006 8:23 AM
To: Robert Dodier
Cc: ***@math.utexas.edu
Subject: Re: [Maxima] ibase and obase
Post by Robert Dodier
For the record here is a reimplementation of ascii-numberp
and some examples. Note the use of the trailing decimal point
to indicate an integer in base 10; this is a useful Lisp-ism inherited
by Maxima.
(defun ascii-numberp (putative-digit)
(and
(characterp putative-digit)
(find
(char-downcase putative-digit)
(subseq "0123456789abcdefghijklmnopqrstuvwxyz" 0 *read-base*))))
Hi Robert,

I have loaded this code and tried it out.

(%i2) block( [ibase:16], a );
(%o2) a
(%i3) block( ibase:16, a );
(%o3) a
(%i4) a;
(%o4) 10

An assignment to ibase in a block doesn't have any consequence inside the
block itself.
Does it make sense then, if this only works in top level?

Maybe one could think about implementing bytestrings.

Volker
Stavros Macrakis
2006-06-20 15:57:03 UTC
Permalink
Post by van Nek
(%i2) block( [ibase:16], a );
(%o2) a
(%i3) block( ibase:16, a );
(%o3) a
(%i4) a;
(%o4) 10
An assignment to ibase in a block doesn't have any consequence inside the block itself.
Does it make sense then, if this only works in top level?
The input lines have already been read by the time they are evaluated, so
ibase cannot have any effect on their reading. Here are examples of how you
could use a locally-bound ibase:

block([ibase:2],readonly("Binary number: "));
Binary number: 1010101010;
682

load("eval_string")$
block([ibase:2],eval_string("1011^111"));
19487171

inbase(str,base):=block([ibase:base],parse_string(str))$
inbase("100",16) => 256

Hope this helps.

-s
van Nek
2006-06-20 17:28:07 UTC
Permalink
Post by Robert Dodier
Volker,
Post by van Nek
(%i2) block( [ibase:16], a );
(%o2) a
(%i3) block( ibase:16, a );
(%o3) a
(%i4) a;
(%o4) 10
An assignment to ibase in a block doesn't have any consequence inside the block itself.
Does it make sense then, if this only works in top level?
That is to be expected. Maxima parses the entire input expression
before evaluating it. So in block([ibase : 16], a) , a is read with the
value of ibase *before* 16 is assigned.
Obviously!
But my question remains the same: Does this make sense, if we can't use a local defined
ibase in a function definition?
Post by Robert Dodier
Post by van Nek
Maybe one could think about implementing bytestrings.
Not sure what you mean here. Maybe you can expand on this point.
Sorry Robert, bytestrings are an interesting but different theme.
What I thought about was a string implementation like what Richard Fateman suggested
Post by Robert Dodier
I think that input of hexadecimal could be done by just adding a function.
For example, read_from_string("ff00",16).
Volker
van Nek
2006-06-20 17:43:43 UTC
Permalink
Here are examples of how you could use a locally-bound
block([ibase:2],readonly("Binary number: "));
Binary number: 1010101010;
682
load("eval_string")$
block([ibase:2],eval_string("1011^111"));
19487171
inbase(str,base):=block([ibase:base],parse_string(str))$
inbase("100",16) => 256
Hope this helps.
Yes, it does.
Thank you Stavros. That is what I was looking for.
Volker

Loading...