'From Cuis 2.0 of 4 January 2010 [latest update: #393] on 12 February 2010 at 10:39:19 am'!

!Number commentStamp: 'jmv 2/12/2010 10:37' prior: 0!
Class Number holds the most general methods for dealing with numbers. Subclasses Float, Fraction, and Integer, and their subclasses, provide concrete representations of a numeric quantity.

All of Number's subclasses participate in a simple type coercion mechanism that supports mixed-mode arithmetic and comparisons.  It works as follows:  If
	self<typeA> op: arg<typeB>
fails because of incompatible types, then it is retried in the following guise:
	(arg adaptTypeA: self) op: arg adaptToTypeA.
This gives the arg of typeB an opportunity to resolve the incompatibility, knowing exactly what two types are involved.  If self is more general, then arg will be converted, and viceVersa.  This mechanism is extensible to any new number classes that one might wish to add to Squeak.  The only requirement is that every subclass of Number must support a pair of conversion methods specific to each of the other subclasses of Number.


Note:
To write an hex number, in Cuis you can do 16rFE and not 16rfe. WRT some proposal to change this, Dan Ingalls said: at http://lists.squeakfoundation.org/pipermail/squeak-dev/2000-March/013368.html :

I will have to admit to a bit of bigotry here.  I was the originator of the numeric format, and I object to a couple of the ANSI decisions regarding the syntax of numeric constants.  I have three reasons for this...

1.  I much prefer 2r1e31 to 2r10000000000000000000000000000000 for the sign bit and 16rFe8 for the high nibble of a 32-bit integer and 10e6 for a million.  Come on. (jmv note: it is actually 16rFe7 hex and 10e5)

2.  I just feel that the current (Squeak) def, which is the original one, is a micro world of simplicity and generality.  Radix, digits and exponent defined analogously over ints, largeInts, and Floats.  That's all.

3.  I have spent entire hours with inquisitive kids, just exploring this micro world.  If they get bored with 2r1e10 then it's time to step out and explore the meaning of 3r11.2.

If I were going to "fix" anything, I think it would be to allow 1r111111111111 = 12.

This may be the issue that finally leads to a parting of the ways in the Squeak Community.

Just Kidding

	- Dan

Note: Cuis does support the Unary numeric system. So
		1r111111111111 = 12
		1r1 = 1
		1r11 = 2
		1r-11 = -2
		1r111 = 3
		1r = 0
See See http://en.wikipedia.org/wiki/Unary_numeral_system and #readBaseOneFrom:!


!Number class methodsFor: 'instance creation' stamp: 'jmv 2/12/2010 10:32'!
readFrom: stringOrStream 
	"Answer a number as described on aStream.  The number may
	include a leading radix specification, as in 16rFADE"
	| value base aStream sign |
	aStream _ (stringOrStream isMemberOf: String)
		ifTrue: [ReadStream on: stringOrStream]
		ifFalse: [stringOrStream].
	(aStream nextMatchAll: 'NaN') ifTrue: [^ Float nan].
	sign _ (aStream peekFor: $-) ifTrue: [-1] ifFalse: [1].
	(aStream nextMatchAll: 'Infinity') ifTrue: [^ Float infinity * sign].
	base _ 10.
	value _ Integer readFrom: aStream base: base.
	(aStream peekFor: $r)
		ifTrue: [
			"<base>r<integer>"
			(base _ value) < 2 ifTrue: [
				base = 1 ifTrue: [ ^Integer readBaseOneFrom: aStream ].
				^self error: 'Invalid radix'].
			(aStream peekFor: $-) ifTrue: [sign _ sign negated].
			value _ Integer readFrom: aStream base: base].
	^ self readRemainderOf: value from: aStream base: base withSign: sign.! !


!Integer class methodsFor: 'instance creation' stamp: 'jmv 2/12/2010 10:38'!
readBaseOneFrom: aStream
	"Unary numeral system
	Supports positive and negative integers.
	See http://en.wikipedia.org/wiki/Unary_numeral_system
	Non-standard features of this system include:
		- The value of a digit does not depend on its position. Thus, one can easily argue that unary is not a positional system at all.
		- Introducing a radix point in this system will not enable representation of non-integer values.
		- The single numeral represents the value 1, not the value 0=b-1.
		- The value 0 cannot be represented (or is implicitly represented by an empty digit string).
	Examples (and equivalent decimal notation)
		1r1 = 10r1
		1r11 = 10r2
		1r111 = 10r3
		1r = 10r0
	"

	| digit value neg |
	neg _ aStream peekFor: $-.
	neg ifFalse: [aStream peekFor: $+].
	value _ 0.
	[ aStream atEnd ]
		whileFalse: [ 
			digit _ aStream next digitValue.
			digit = 1
				ifTrue: [value _ value + digit]
				ifFalse: [
					aStream skip: -1.
					neg ifTrue: [^ value negated].
					^ value]].
	neg ifTrue: [ ^ value negated ].
	^ value! !

Number class removeSelector: #readFrom:base:!
