Numbers, Booleans & Type Conversion
Numbers in Dart
Dart has three numeric types that form a hierarchy: num is the parent type, with int and double as its children. Understanding when to use each type is essential for writing correct and efficient Dart code.
The Number Type Hierarchy
// num is the parent of both int and double
num anyNumber = 42; // can hold int
anyNumber = 3.14; // can also hold double
int wholeNumber = 42; // only whole numbers
double decimalNumber = 3.14; // only decimal numbers
Integers (int)
Integers represent whole numbers without a decimal point. On native platforms (mobile, desktop), Dart integers are 64-bit signed values, giving a range from about -9.2 quintillion to 9.2 quintillion. On the web (compiled to JavaScript), they follow JavaScript’s number precision.
Working with Integers
void main() {
int age = 28;
int negative = -100;
int zero = 0;
// Different integer literal formats
int decimal = 255;
int hex = 0xFF; // 255 in hexadecimal
int binary = 0b11111111; // 255 in binary (Dart 3+)
print(decimal == hex); // true
print(hex == binary); // true
// Large numbers with underscore separators for readability
int population = 7_900_000_000;
int bytes = 1_073_741_824;
print(population); // 7900000000
print(bytes); // 1073741824
}
_) in large numbers to improve readability. Dart ignores them completely -- 1_000_000 is exactly the same as 1000000.Doubles (double)
Doubles represent 64-bit floating-point numbers following the IEEE 754 standard. They can hold fractional values, very large numbers, and very small numbers using scientific notation.
Working with Doubles
void main() {
double pi = 3.14159265;
double price = 29.99;
double tiny = 0.001;
double negative = -273.15;
// Scientific notation
double speed = 3.0e8; // 300,000,000 (speed of light m/s)
double small = 1.6e-19; // 0.00000000000000000016
print(speed); // 300000000.0
print(small); // 1.6e-19
// Integer assigned to double automatically becomes double
double value = 42; // stored as 42.0
print(value); // 42.0
}
0.1 + 0.2 equals 0.30000000000000004, not 0.3. For financial calculations, consider working with integers (cents instead of dollars) or using a decimal library.Useful Number Properties and Methods
Number Properties
void main() {
int number = -42;
double decimal = 3.7;
// Properties
print(number.isNegative); // true
print(number.isEven); // true
print(number.isOdd); // false
print(decimal.isFinite); // true
print(decimal.isInfinite); // false
print(decimal.isNaN); // false
// Special double values
print(double.infinity); // Infinity
print(double.negativeInfinity); // -Infinity
print(double.nan); // NaN
print(double.maxFinite); // 1.7976931348623157e+308
}
Number Methods
void main() {
double value = 3.7;
// Rounding
print(value.round()); // 4 (nearest integer)
print(value.floor()); // 3 (round down)
print(value.ceil()); // 4 (round up)
print(value.truncate()); // 3 (remove decimal part)
// Absolute value
print((-42).abs()); // 42
print((-3.14).abs()); // 3.14
// Clamp to a range
int score = 150;
print(score.clamp(0, 100)); // 100 (clamped to max)
int low = -10;
print(low.clamp(0, 100)); // 0 (clamped to min)
// Formatting doubles
double pi = 3.14159265;
print(pi.toStringAsFixed(2)); // 3.14
print(pi.toStringAsPrecision(4)); // 3.142
}
Arithmetic Operators
Dart supports all standard arithmetic operators:
Basic Arithmetic
void main() {
int a = 10;
int b = 3;
print(a + b); // 13 (addition)
print(a - b); // 7 (subtraction)
print(a * b); // 30 (multiplication)
print(a / b); // 3.3333... (division -- always returns double)
print(a ~/ b); // 3 (integer division -- truncates)
print(a % b); // 1 (modulo -- remainder)
// Unary operators
int c = 5;
print(-c); // -5 (negate)
}
/ always returns a double in Dart, even when dividing two integers. Use ~/ (truncating division) when you want an integer result.The dart:math Library
For advanced mathematical operations, import the dart:math library:
Using dart:math
import 'dart:math';
void main() {
// Constants
print(pi); // 3.141592653589793
print(e); // 2.718281828459045
// Power and square root
print(pow(2, 10)); // 1024 (2^10)
print(sqrt(144)); // 12.0
// Min and max
print(min(5, 10)); // 5
print(max(5, 10)); // 10
// Logarithm
print(log(e)); // 1.0
// Random numbers
var random = Random();
print(random.nextInt(100)); // 0-99
print(random.nextDouble()); // 0.0-1.0
print(random.nextBool()); // true or false
}
Booleans (bool)
The bool type has exactly two values: true and false. Unlike JavaScript, Dart does not have truthy and falsy values. Only actual bool values can be used in conditions.
Boolean Basics
void main() {
bool isActive = true;
bool isAdmin = false;
// Direct use in conditions
if (isActive) {
print('User is active');
}
// Dart does NOT have truthy/falsy like JavaScript
// if (1) { ... } // ERROR! 1 is not a bool
// if ('hello') { ... } // ERROR! String is not a bool
// if (null) { ... } // ERROR! null is not a bool
// You must explicitly compare
int count = 5;
if (count > 0) { // This works -- comparison returns bool
print('Has items');
}
}
0, "", null, or undefined to false. You must always use explicit boolean expressions in conditions.Logical Operators
Boolean Logic
void main() {
bool a = true;
bool b = false;
// AND -- both must be true
print(a && b); // false
print(a && a); // true
// OR -- at least one must be true
print(a || b); // true
print(b || b); // false
// NOT -- inverts the value
print(!a); // false
print(!b); // true
// Practical example
int age = 25;
bool hasLicense = true;
bool canDrive = age >= 18 && hasLicense;
print('Can drive: \$canDrive'); // Can drive: true
}
Comparison Operators
Comparison operators return boolean values and are used extensively in conditions:
All Comparison Operators
void main() {
int x = 10;
int y = 20;
print(x == y); // false (equal)
print(x != y); // true (not equal)
print(x > y); // false (greater than)
print(x < y); // true (less than)
print(x >= 10); // true (greater or equal)
print(x <= 20); // true (less or equal)
// Chaining comparisons
int score = 75;
bool passed = score >= 60 && score <= 100;
print('Passed: \$passed'); // Passed: true
}
Type Conversion
Converting between types is a common task in Dart. Here are all the important conversions you need to know:
Between Number Types
int and double Conversion
void main() {
// int to double
int whole = 42;
double asDouble = whole.toDouble();
print(asDouble); // 42.0
// double to int (truncates decimal part)
double decimal = 9.99;
int asInt = decimal.toInt();
print(asInt); // 9 (not rounded!)
// double to int (rounded)
int rounded = decimal.round();
print(rounded); // 10
// Safe: int can always become double
// Careful: double to int loses precision
}
Numbers to Strings
Number to String
void main() {
int count = 42;
double price = 9.99;
// Basic conversion
String countStr = count.toString();
String priceStr = price.toString();
print(countStr); // '42'
print(priceStr); // '9.99'
// Formatted conversion
print(price.toStringAsFixed(1)); // '10.0'
print(price.toStringAsFixed(3)); // '9.990'
print(12345.toStringAsExponential()); // '1.2345e+4'
// Using string interpolation (auto-converts)
print('Count: \$count, Price: \$price');
}
Strings to Numbers
String to Number (Safe vs Unsafe)
void main() {
// UNSAFE -- throws FormatException on invalid input
int a = int.parse('42');
double b = double.parse('3.14');
print(a); // 42
print(b); // 3.14
// SAFE -- returns null on invalid input
int? c = int.tryParse('abc');
double? d = double.tryParse('xyz');
print(c); // null
print(d); // null
// Pattern: tryParse with fallback
String userInput = 'not a number';
int value = int.tryParse(userInput) ?? 0;
print(value); // 0 (fallback used)
// Parse hex string
int hex = int.parse('FF', radix: 16);
print(hex); // 255
}
Boolean Conversions
Boolean to/from Other Types
void main() {
// Bool to String
bool active = true;
String activeStr = active.toString();
print(activeStr); // 'true'
// String to Bool (no built-in parse, do it manually)
String input = 'true';
bool parsed = input.toLowerCase() == 'true';
print(parsed); // true
// Common pattern: number to bool
int status = 1;
bool isActive = status == 1;
print(isActive); // true
// Bool to int
bool flag = true;
int flagInt = flag ? 1 : 0;
print(flagInt); // 1
}
The Null-Aware Operators
When working with type conversions, values can often be null. Dart provides null-aware operators to handle this elegantly:
Null-Aware Operators with Conversions
void main() {
// ?? -- provide default if null
int? parsed = int.tryParse('abc');
int value = parsed ?? 0;
print(value); // 0
// Shorthand in one line
int age = int.tryParse('25') ?? 0;
print(age); // 25
int invalid = int.tryParse('hello') ?? -1;
print(invalid); // -1
}
Practical Example: Building a Calculator
Mini Calculator
import 'dart:math';
void main() {
double a = 15.0;
double b = 4.0;
print('--- Calculator ---');
print('\$a + \$b = ${a + b}'); // 19.0
print('\$a - \$b = ${a - b}'); // 11.0
print('\$a * \$b = ${a * b}'); // 60.0
print('\$a / \$b = ${(a / b).toStringAsFixed(2)}'); // 3.75
print('\$a % \$b = ${a % b}'); // 3.0
print('\$a ^ \$b = ${pow(a, b)}'); // 50625.0
print('sqrt(\$a) = ${sqrt(a).toStringAsFixed(4)}'); // 3.8730
// Is the result a whole number?
double result = a / b;
bool isWhole = result == result.roundToDouble();
print('Is \$a/\$b a whole number? \$isWhole'); // false
}
Practice Exercise
Open DartPad and create a program that: (1) Declares two integer variables and two double variables. (2) Performs all arithmetic operations (+, -, *, /, ~/, %) and prints the results. (3) Uses dart:math to calculate the square root and power of a number. (4) Converts a double price to an integer using round(), floor(), and ceil() and compares the results. (5) Uses tryParse with the ?? operator to safely convert a string to a number with a fallback value.