简体   繁体   English

如何在 Dart 中进行整数除法?

[英]How to do Integer division in Dart?

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'.'我在 Dart 中使用整数除法时遇到了问题,因为它给了我错误: “打破异常:类型 'double' 不是类型 'c' 的 'int' 的子类型。”

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.如您所见,我期望结果应该是 2,或者说,即使除法 'a' 或 'b' 的结果是浮点/双精度值,它也应该直接转换为整数值,而不是抛出这样的错误。

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).我有一个使用 .round()/.ceil()/.floor() 的解决方法,但这在我的程序中是不够的,这个小操作很关键,因为它在一个游戏更新中被调用了数千次(或你可以在 requestAnimationFrame 中说)。

I have not found any other solution to this yet, any idea?我还没有找到任何其他解决方案,知道吗? Thanks.谢谢。

Dart version: 1.0.0_r30798飞镖版本:1.0.0_r30798

That is because Dart uses double to represent all numbers in dart2js .那是因为Dart 使用double来表示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).实际上,建议在处理num时使用num类型,除非您有充分的理由将其设为int (例如在 for 循环中)。 If you want to keep using int , use truncating division like this:如果您想继续使用int ,请使用如下截断除法:

int a = 500;
int b = 250;
int c;

c = a ~/ b;

Otherwise, I would recommend to utilize num type.否则,我会建议使用num类型。

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.如果你想定义分数应该如何处理。

Short Answer简答

Use c = a ~/ b .使用c = a ~/ b

Long Answer长答案

According to the docs, int are numbers without a decimal point, while double are numbers with a decimal point.根据文档, int是没有小数点的数字,而double是有小数点的数字。

Both double and int are subtypes of num . doubleint都是num子类型。

When two integers are divided using the / operator, the result is evaluated into a double .当两个整数使用/运算符相除时,结果被计算为double And the c variable was initialized as an integer.并且c变量被初始化为一个整数。 There are at least two things you can do:您至少可以做两件事:

  1. Use c = a ~/ b .使用c = a ~/ b

The ~/ operator returns an int . ~/运算符返回一个int

  1. Use var c;使用var c; . . This creates a dynamic variable that can be assigned to any type, including a double and int and String etc.这将创建一个可以分配给任何类型的动态变量,包括doubleint以及String等。

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): 常规除法运算符/将始终在运行时返回double值(请参阅文档):

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 .您可能已经注意到,我为第二个示例(用于常规除法运算符)而不是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 .编译器会在编译时简单地将4 / 2转换为2 ,这显然是一个int The loop prevents the compiler from evaluating the expression.循环阻止编译器评估表达式。

As long as your division happens at runtime (ie 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.只要您的除法发生在运行时(即在编译时无法预测的变量), / ( double ) 和~/ ( int ) 运算符的返回类型将是您将在运行时看到的表达式类型。

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.一般而言,常规除法运算符/始终返回double值,截断除法可用于获得int结果。

Compiler optimization might, however, cause some funky results :)然而,编译器优化可能会导致一些奇怪的结果:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM