### Numbers in Dart

(This is part 10 in an ongoing series about Dart. Check out part 9, a Dart SDK quick tour.)

Intro

It's time to look at numbers in Dart. Wait, where are you going? Come back, numbers are cool! This will be interesting, for reals. I can at least promise this will be easy and quick, for numbers in Dart aren't complicated. If you're compiling to JavaScript, though, there are a few edge cases (bugs?) so I encourage you to not skip this episode.

The Basics

Like everything else in Dart, numbers are objects. In fact, numbers are specified as interfaces.

Numbers come in two flavors in Dart: integers of arbitrary size and decimal 64 bit doubles as specified by the IEEE 754 standard. Both int and double are subinterfaces of num.
 num is the supertype, int and double extend num.
The num interface defines the basics like +, -, /, and *. Num is where you'll also find abs(), ceil(), and floor(), among other methods.

Int

Integers are numbers without a decimal point. For example:

``````  var x = 1;
print(x);
print(x is num); // true in both Dart VM and JS
print(x is int); // true in both Dart VM and JS``````

You may also specify hexadecimals with the 0x prefix.

``````  var hex = 0xDEADBEEF;
print(hex); // 873735928559
print(hex is num); // true in both Dart VM and JS
print(hex is int); // true in both Dart VM and JS
print(hex is! double); // true in Dart VM, FALSE when compiled to JavaScript
``````

Alert: the last line in the above sample, the result is different between the Dart VM and Dart compiled to JavaScript. I've opened a bug to see if this is by design.

Integers can be of arbitrary precision. For example:

``````  var bigInt = 346538465234590347592847298346243459756895347698465298346583746592374652378462347569234765834765947569827346583465243765923847659234765928347659567398475647495873984572947593470294387093493456870849216348723763945678236420938467345762304958724596873045876234572037862934765294365243652548673456705673465273465246734506873456729457623845623456234650457693475603768922346728346256;
print(bigInt); // correct in Dart VM, Infinity when compiled to JavaScript
print(bigInt is num); // true in both Dart VM and JS
print(bigInt is int); // true in both Dart VM and JS
``````

While the above will work in the Dart VM, when compiled to JavaScript, the large number becomes Infinity.

Alert: JavaScript only supports +/- 9007199254740992 for integers and (at least in V8) 1.7976931348623157e+308 for Number.MAX_VALUE. I've opened a bug to discuss this, as the above code functions differently in Dart VM and JavaScript.

You might see Dart code that explicitly adds a + prefix to the number, though it isn't necessary.

``````  var positive = +12345;
print(positive); // 12345
print(positive is num); // true
print(positive is int); // true
``````

Double

If the number includes a decimal, it is a 64 bit double that follows IEEE 754 standard.

A simple example:

``````  var y = 1.1;
print(y);
print(y is num); // true in both Dart VM and JS
print(y is double); // true in both Dart VM and JS
``````

Exponent notation is supported:

``````  var exponents = 1.42e5;
print(exponents); // prints 142000.0 in Dart VM, 142000 when compiled to JavaScript
print(exponents is num); // true in both Dart VM and JS
print(exponents is! int); // true in Dart VM, FALSE when compiled to JS
print(exponents is double); // true in both Dart VM and JS
``````

Here again you can see slight differences between what Dart VM and JavaScript will do. The generated JavaScript code looks like this:

``````  // generated JavaScript from Frog, as of 2012-02-04
var exponents = (142000.0);
print(exponents);
print((typeof(exponents) == 'number'));
print((typeof(exponents) != 'number')); // this is FALSE, see corresponding Dart code above
print((typeof(exponents) == 'number'));
``````

NaN

Dividing zero by zero will result in "not a number" in Dart, similar to JavaScript but unlike Java.

The num interface provides a simple check for isNaN().

``````  var nan = 0 / 0;
print(nan.isNaN()); // true in both Dart VM and JS
``````

Converting to and from a String

A common requirement is to turn a number into a String, or a String into a number.

Parsing a String to an int uses the Math class:

``````  var one = Math.parseInt("1");
print(one);  // 1
print(one is int);  // true
``````

Parsing a String into a double is similar:

``````  var onePointOne = Math.parseDouble("1.1");
print(onePointOne); // 1.1
print(onePointOne is double); // true
``````

Attempting to format a string that isn't a number will throw a BadNumberFormatException.

``````  try {
var gook = Math.parseInt("foo");
} catch(BadNumberFormatException e) {
print(e); // BadNumberFormatException: 'foo'
}

``````

Going the other way, converting numbers to Strings, is also very easy thanks to toString().

``````  String oneAsString = 1.toString();
print(oneAsString); // 1
print(oneAsString is String);
``````

For doubles, toStringAsFixed(int fractionDigits) will truncate the decimal digits:

``````  print(3.14159.toStringAsFixed(2)); // 3.14
``````

Misc methods

A potentially unfamiliar change is the methods like ceil() and abs() are found on the num interface, and not in Math.

``````  // absolute value is a method on num
print((-4).abs() == 4);

// ceil and floor are also methods on num
print(3.25.ceil() == 4.0);
print(3.25.floor() == 3.0);

// round will round up if .5 or greater, otherwise will round down
print(3.25.round() == 3);
print(3.89.round() == 4);
print(3.5.round() == 4);
print(3.49.round() == 3);

// truncates the decimal digits
print(3.24532.truncate() == 3.0);

// convert a double to an int
print(3.24.toInt() == 3);
``````

Bit manipulating

The num interface also specifies the traditional bit shifting, and'ing, and or'ing. Some simple examples:

``````  print(3<<1 == 6); // 0011 << 1 == 0110
print(3>>1 == 1); // 0011 >> 1 == 0001

print((3|4) == 7); // 0011 | 0100 == 0111
``````

Summary

Dart supplies a num interface with two subinterfaces: int and double. Integers are arbitrary precision, meaning they have arbitrary size. Doubles are 64 bit decimals that follow IEEE 754 spec.

Generally speaking, numbers function the same across native Dart and Dart compiled to JavaScript, but there are some subtle differences. For example, watch out for very large numbers and checking the difference between int and double in JavaScript (currently everything is checked against number in JavaScript from the Frog compiler.)

Next Steps

Read more of my Dart posts, try Dart in your browser, browse the API docs, or file an issue request. Dart is getting ready, please send us your feedback!