Browse files

Passing test cases again

  • Loading branch information...
1 parent c8c4fbc commit b3d6f8b8e1a9bc67d360fec14e0124f06a47ade6 Danny Yoo committed May 9, 2011
Showing with 76 additions and 41 deletions.
  1. +6 −2 README
  2. +55 −24 src/js-numbers.js
  3. +15 −15 test/tests.js
View
8 README
@@ -93,12 +93,16 @@ fromString: string -> (scheme-number | false)
returns false.
fromFixnum: javascript-number -> scheme-number
- Convert from a javascript number to a scheme-number.
+ Convert from a javascript number to a scheme number. If the
+ number looks like an integer, represents as an exact integer.
+ Otherwise, represents as a float. If you need more precision over
+ the representation, use makeFloat or makeRational instead.
makeRational: javascript-number javascript-number? -> scheme-number
Low level constructor: Constructs a rational with the given
numerator and denominator. If only one argument is given, assumes
- the denominator is 1.
+ the denominator is 1. The numerator and denominator must be
+ integers.
makeFloat: javascript-number -> scheme-number
Low level constructor: constructs a floating-point number.
View
79 src/js-numbers.js
@@ -78,14 +78,48 @@ if (typeof(exports) !== 'undefined') {
}
var nf = Math.floor(x);
if (nf === x) {
- if (isOverflow(nf)) {
- return makeBignum(x);
- } else {
+ if (isOverflow(nf)) {
+ return makeBignum(expandExponent(x+''));
+ } else {
return nf;
}
} else {
- return FloatPoint.makeInstance(x);
+ return FloatPoint.makeInstance(x);
+ }
+ };
+
+ var expandExponent = function(s) {
+ var match = s.match(scientificPattern), mantissaChunks, exponent;
+ if (match) {
+ mantissaChunks = match[1].match(/^([^.]*)(.*)$/);
+ exponent = Number(match[2]);
+
+ if (mantissaChunks[2].length === 0) {
+ return mantissaChunks[1] + zfill(exponent);
+ }
+
+ if (exponent >= mantissaChunks[2].length - 1) {
+ return (mantissaChunks[1] +
+ mantissaChunks[2].substring(1) +
+ zfill(exponent - (mantissaChunks[2].length - 1)));
+ } else {
+ return (mantissaChunks[1] +
+ mantissaChunks[2].substring(1, 1+exponent));
+ }
+ } else {
+ return s;
+ }
+ };
+
+ // zfill: integer -> string
+ // builds a string of "0"'s of length n.
+ var zfill = function(n) {
+ var buffer = [];
+ buffer.length = n;
+ for (var i = 0; i < n; i++) {
+ buffer[i] = '0';
}
+ return buffer.join('');
};
@@ -1497,18 +1531,17 @@ if (typeof(exports) !== 'undefined') {
var fl = Math.floor(v);
var ce = Math.ceil(v);
if (_integerIsZero(fl % 2)) {
- return fromFixnum(fl);
+ return fl;
}
else {
- return fromFixnum(ce);
+ return ce;
}
} else {
- return fromFixnum(Math.round(this.n / this.d));
+ return Math.round(this.n / this.d);
}
};
-
Rational.makeInstance = function(n, d) {
if (n === undefined)
throwRuntimeError("n undefined", n, d);
@@ -1931,8 +1964,6 @@ if (typeof(exports) !== 'undefined') {
// either be plt.type.Rational or plt.type.FloatPoint.
Complex.makeInstance = function(r, i){
if (i === undefined) { i = 0; }
- if (typeof(r) === 'number') { r = fromFixnum(r); }
- if (typeof(i) === 'number') { i = fromFixnum(i); }
if (isExact(i) && isInteger(i) && _integerIsZero(i)) {
return r;
}
@@ -2323,10 +2354,10 @@ if (typeof(exports) !== 'undefined') {
var rationalRegexp = new RegExp("^([+-]?\\d+)/(\\d+)$");
- var bignumScientificPattern = new RegExp("^([+-]?\\d*)\\.?(\\d*)[Ee](\\+?\\d+)$");
var complexRegexp = new RegExp("^([+-]?[\\d\\w/\\.]*)([+-])([\\d\\w/\\.]*)i$");
- var flonumRegexp = new RegExp("^([+-]?\\d*)\\.?(\\d*)$");
- var digitRegexp = new RegExp("\\d");
+ var digitRegexp = new RegExp("^[+-]?\\d+$");
+ var flonumRegexp = new RegExp("^([+-]?\\d*)\\.(\\d*)$");
+ var scientificPattern = new RegExp("^([+-]?\\d*\\.?\\d*)[Ee](\\+?\\d+)$");
// fromString: string -> (scheme-number | false)
var fromString = function(x) {
@@ -2342,6 +2373,7 @@ if (typeof(exports) !== 'undefined') {
fromString(cMatch[2] + (cMatch[3] || "1")));
}
+ // Floating point tests
if (x === '+nan.0' || x === '-nan.0')
return FloatPoint.nan;
if (x === '+inf.0')
@@ -2351,13 +2383,17 @@ if (typeof(exports) !== 'undefined') {
if (x === "-0.0") {
return NEGATIVE_ZERO;
}
- if (x.match(digitRegexp) &&
- (x.match(flonumRegexp) || x.match(bignumScientificPattern))) {
+ if (x.match(flonumRegexp) || x.match(scientificPattern)) {
+ return FloatPoint.makeInstance(Number(x));
+ }
+
+ // Finally, integer tests.
+ if (x.match(digitRegexp)) {
var n = Number(x);
if (isOverflow(n)) {
return makeBignum(x);
} else {
- return fromFixnum(n);
+ return n;
}
} else {
return false;
@@ -3619,15 +3655,10 @@ if (typeof(exports) !== 'undefined') {
// makeBignum: string -> BigInteger
var makeBignum = function(s) {
if (typeof(s) === 'number') { s = s + ''; }
- var match = s.match(bignumScientificPattern);
- if (match) {
- return new BigInteger(match[1]+match[2] +
- zerostring(Number(match[3]) - match[2].length),
- 10);
- } else {
- return new BigInteger(s, 10);
- }
+ s = expandExponent(s);
+ return new BigInteger(s, 10);
};
+
var zerostring = function(n) {
var buf = [];
for (var i = 0; i < n; i++) {
View
30 test/tests.js
@@ -158,15 +158,15 @@ describe('fromString', {
'floats': function() {
assertEquals(makeFloat(42.1), fromString("42.1"));
- assertEquals(makeFloat(0.1), fromString(".1"));
- assertEquals(makeFloat(0.23), fromString("0.23"));
- assertEquals(makeFloat(0.1), fromString("+.1"));
- assertEquals(makeFloat(-0.1), fromString("-.1"));
- assertEquals(makeFloat(-0.123423), fromString("-.123423"));
- assertEquals(makeFloat(123.45), fromString("123.45"));
- assertEquals(makeFloat(4123.423), fromString("4.123423e3"));
- assertEquals(makeFloat(10000000000000000.2),
- fromString("10000000000000000.2"));
+ assertEquals(makeFloat(0.1), fromString(".1"));
+ assertEquals(makeFloat(0.23), fromString("0.23"));
+ assertEquals(makeFloat(0.1), fromString("+.1"));
+ assertEquals(makeFloat(-0.1), fromString("-.1"));
+ assertEquals(makeFloat(-0.123423), fromString("-.123423"));
+ assertEquals(makeFloat(123.45), fromString("123.45"));
+ assertEquals(makeFloat(4123.423), fromString("4.123423e3"));
+ assertEquals(makeFloat(10000000000000000.2),
+ fromString("10000000000000000.2"));
},
'complex': function() {
@@ -226,11 +226,11 @@ describe('fromFixnum', {
},
'bignums': function() {
- assertEquals(makeBignum("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
- fromFixnum(10e100));
+ assertTrue(equals(fromString("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
+ fromFixnum(10e100)));
- assertEquals(makeBignum("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
- fromFixnum(10e200));
+ assertTrue(equals(fromString("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
+ fromFixnum(10e200)));
},
'floats': function() {
@@ -520,8 +520,8 @@ describe('eqv', {
},
'fixnum / float ' : function() {
- value_of(eqv(fromFixnum(1024), makeFloat(1024))).should_be_false();
- value_of(eqv(fromFixnum(1024), makeFloat(1024.0001))).should_be_false();
+ value_of(eqv(makeRational(1024), makeFloat(1024))).should_be_false();
+ value_of(eqv(makeRational(1024), makeFloat(1024.0001))).should_be_false();
},
'fixnum / complex' : function() {

0 comments on commit b3d6f8b

Please sign in to comment.