How to do Integer division in Dart?
DartDart Problem Overview
I have trouble with integer division in Dart as it gives me error: 'Breaking on exception: type 'double' is not a subtype of type 'int' of 'c'.'
Here's the following code:
int a = 500;
int b = 250;
int c;
c = a / b; // <-- Gives warning in Dart Editor, and throws an error in runtime.
As you see, I was expecting that the result should be 2, or say, even if division of 'a' or 'b' would have a result of a float/double value, it should be converted directly to integer value, instead of throwing error like that.
I have a workaround by using .round()/.ceil()/.floor(), but this won't suffice as in my program, this little operation is critical as it is called thousands of times in one game update (or you can say in requestAnimationFrame).
I have not found any other solution to this yet, any idea? Thanks.
Dart version: 1.0.0_r30798
Dart Solutions
Solution 1 - Dart
That is because Dart uses double
to represent all numbers in dart2js
. You can get interesting results, if you play with that:
Code:
int a = 1;
a is int;
a is double;
Result:
true
true
Actually, it is recommended to use type num
when it comes to numbers, unless you have strong reasons to make it int
(in for loop, for example). If you want to keep using int
, use truncating division like this:
int a = 500;
int b = 250;
int c;
c = a ~/ b;
Otherwise, I would recommend to utilize num
type.
Solution 2 - Dart
Integer division is
c = a ~/ b;
you could also use
c = (a / b).floor();
c = (a / b).ceil();
if you want to define how fractions should be handled.
Solution 3 - Dart
Short Answer
Use c = a ~/ b
.
Long Answer
According to the docs, int
are numbers without a decimal point, while double
are numbers with a decimal point.
Both double
and int
are subtypes of num
.
When two integers are divided using the /
operator, the result is evaluated into a double
. And the c
variable was initialized as an integer. There are at least two things you can do:
- Use
c = a ~/ b
.
The ~/
operator returns an int
.
- Use
var c;
. This creates a dynamic variable that can be assigned to any type, including adouble
andint
andString
etc.
Solution 4 - Dart
Truncating division operator
You can use the truncating division operator ~/
to get an integer result from a division operation:
4 ~/ 2; // 2 (int)
Division operator
The regular division operator /
will always return a double
value at runtime (see the docs):
for (var i = 4; i == 4; i = 3) {
i / 2; // 2 (double)
}
Runtime versus compile time
You might have noticed that I wrote a loop for the second example (for the regular division operator) instead of 4 / 2
.
The reason for this is the following:
When an expression can be evaluated at compile time, it will be simplified at that stage and also be typed accordingly. The compiler would simply convert 4 / 2
to 2
at compile time, which is then obviously an int
. The loop prevents the compiler from evaluating the expression.
As long as your division happens at runtime (i.e. with variables that cannot be predicted at compile time), the return types of the /
(double
) and ~/
(int
) operators will be the types you will see for your expressions at runtime.
See this fun example for further reference.
Conclusion
Generally speaking, the regular division operator /
always returns a double
value and truncate divide can be used to get an int
result instead.
Compiler optimization might, however, cause some funky results :)