skip to content

In Dart, how are int, double and num related, and when does Dart convert between int and double for you?

level: juniorimportance: should knowfreq 52%

answer

  1. num is the common supertype
  2. integer literal becomes double
  3. never double to int silently
  4. toInt, round, truncate
  5. bool has no truthiness

basics

~20 s

In Dart, int and double are both subtypes of num. An integer literal becomes a double where a double is expected, as in double z = 1, but a double never converts to int implicitly; you call toInt(), round() or truncate().

solid answer

~50 s

`num` is the supertype of `int` and `double` and holds the shared operators and methods like `abs()`, `ceil()` and `floor()`; bitwise operators live on `int` only. On native platforms `int` is a 64-bit integer and `double` a 64-bit IEEE 754 float. Dart does very little implicit conversion: an **integer literal** becomes a `double` in a `double` context, so `double price = 12;` is `12.0`, but an `int` variable is not converted, and a `double` never becomes an `int` on its own: `int n = 2.5;` is a compile error, and you choose `toInt()`, `round()`, `truncate()`, `ceil()` or `floor()`. Mixing the two in arithmetic gives a `double`. A `num` variable can hold either, which suits values like a menu item's rating. Number literals are compile-time constants, and since language 3.6 you can write `1_000_000` with digit separators.

code

dart · 13 lines
dart
void main() {
  double price = 12; // integer literal becomes 12.0
  const quantity = 3; // int
  final total = price * quantity; // mixed arithmetic: double 36.0
  final rounded = 12.6.round(); // 13
  final truncated = 12.6.toInt(); // 12
  num rating = 4;
  rating += 0.5; // num can hold int or double
  const priceCents = 1_999; // digit separators need language 3.6+
  print('$price $total $rounded $truncated $rating $priceCents');
  // int bad = 12.6; // error: double can't be assigned to int
  // if (quantity) {} // error: conditions must be bool
}

go deeper

for a junior

Recall that int and double share the supertype num and that only integer literals convert to double automatically.

for a middle

Explain why an int variable is not assignable to double, how rounding methods differ, and when num is the right type.

for a senior

Choose number types for money, counters and ratings deliberately, and keep conversions explicit at data boundaries.

for a principal

Set conventions for numeric types in shared models so precision and platform behaviour are decided once.

## The number hierarchy Every Dart number is an object. Two concrete types exist, with a common supertype: | Type | What it holds | Native representation | |---|---|---| | `num` | Either an `int` or a `double` | Supertype only | | `int` | Whole numbers | 64-bit two's complement, -2^63 to 2^63-1 | | `double` | Fractional numbers | 64-bit IEEE 754 | `num` carries the shared API: `+`, `-`, `*`, `/`, comparison, `abs()`, `ceil()`, `floor()`, `round()`, `toInt()`, `toDouble()` and others. The bitwise and shift operators (`&`, `|`, `^`, `~`, `<<`, `>>`, `>>>`) are defined on `int` only. On the web the representation differs, which is a topic of its own. ## Literals - `1`, `0xDEADBEEF` and `1_000_000` are `int` literals. - `1.1`, `1.42e5` and `0.000_000_000_01` are `double` literals. - Digit separators (`_`) need language version 3.6 or later. - Number literals are compile-time constants, and arithmetic on constant numbers is constant too. ## Where Dart converts for you Dart's conversions are deliberately narrow: 1. **Integer literal to double.** In a context that expects a `double`, an integer literal is treated as a double literal: `double z = 1;` is equivalent to `double z = 1.0;`. 2. **Mixed arithmetic.** An operation that mixes an `int` and a `double` produces a `double`. 3. **Nothing else.** An `int` *variable* is not converted when assigned to a `double` variable; a `double` is never narrowed to `int`; strings are never parsed implicitly. ```dart double price = 12; // OK: literal becomes 12.0 int quantity = 3; // double total = quantity; // error: int can't be assigned to double double total = quantity.toDouble(); // int rounded = 12.6; // error: double can't be assigned to int int rounded = 12.6.round(); // 13 ``` ## Choosing the conversion | Method | 12.6 | -12.6 | |---|---|---| | `toInt()` / `truncate()` | 12 | -12 | | `round()` | 13 | -13 | | `floor()` | 12 | -13 | | `ceil()` | 13 | -12 | `toInt()` truncates toward zero, which surprises people who expected rounding. ## Using num Declaring a variable as `num` lets it hold both kinds: ```dart num rating = 4; rating += 0.5; // now a double, 4.5 ``` It is useful at API boundaries that accept either kind, such as a rating or a quantity from a menu feed. Inside calculations, a precise `int` or `double` is usually clearer. ## Money in a menu importer A `double` cannot represent most decimal fractions exactly, so prices summed as doubles drift by tiny amounts. The usual Dart choice is to store prices as `int` cents and divide only for display. That choice also sidesteps web differences in how doubles print. ## Special double values `double` also has values that are not ordinary numbers: - `double.nan` (for example the result of `0 / 0`) is not equal to itself, so test it with `isNaN`, never with `==`. - `double.infinity` and `double.negativeInfinity` come from dividing a non-zero number by zero; test with `isInfinite`. - `0.0` and `-0.0` compare equal with `==`. Calling `toInt()` or `round()` on NaN or infinity throws an `UnsupportedError`, so validate imported numbers before converting them. ## A short answer to give "`int` and `double` are both `num`. Dart only widens integer *literals* to double automatically; everything else is an explicit call such as `toDouble()`, `round()` or `toInt()`, and `toInt()` truncates. I use `num` only where either kind is genuinely acceptable." ## bool, briefly Dart's `bool` has exactly two values, `true` and `false`. There is no truthiness: `if (count)` with an `int` is a compile error (`non_bool_condition`), so you write `if (count != 0)`.

  • Can a Dart int be used directly as an if condition?
    No. Conditions must have static type `bool`, and `bool` has only `true` and `false`. `if (count)` is a compile error (`non_bool_condition`); write `if (count != 0)`. The same applies to strings and nullable values: check `isEmpty` or `== null` explicitly.
  • Why does double total = quantity; fail when quantity is an int variable, while double z = 1; works?
    Only integer *literals* are reinterpreted as doubles in a double context. An `int` variable already has static type `int`, which is not a subtype of `double`, so you must convert with `quantity.toDouble()`.

saying these in an interview costs you the question

  • Dart converts a double to int automatically by truncating
  • int and double are unrelated types with no common supertype
  • toInt() rounds to the nearest integer
  • Any int variable can be assigned to a double variable
  • A non-zero int counts as true in an if condition