我是Dart的新手,刚从c#移植一个项目。其中在整个代码中使用了int32位。
像这样的简单表达式
(someInt1 * ((someInt2 * someInt3) - someInt4 - (someInt5 * someInt6) - someInt7 )
在比较时会给出不一致的结果,就像在c代码中一样,它会超出其大小并返回负值,但这已经在代码中处理过了,这正是我所需要的。
有没有办法我可以故意使用32位int而不是Dart的64位?
Dart没有本机32位整数类型。int
类型在本机运行时是64位2的补码类型,在编译为JavaScript时是非小数64位浮点类型(因为JavaScript就是这样(。
最通用的解决方案是使用fixnum
包中的Int32
类型。然后其他人替你担心这个问题。它的效率低于仅使用int
操作,但它将保持一致的32位语义。
根据int
类型的溢出行为,它不会在所有平台上都起同样的作用。如果您只关心本机代码,并且您的表达式像上面一样只使用*
、-
和+
,那么您可以对结果调用toSigned
。这会给你结果的低32位,这与整个计算使用32位数字的结果相同:
var result =
(someInt1 * ((someInt2 * someInt3) - someInt4 - (someInt5 * someInt6) - someInt7).toSigned(32);
它实际上并没有使用32位数字,如果你也做除法,它也不起作用。当编译到JavaScript时,它将不起同样的作用,因为当中间结果大于253时的溢出行为不同。
您可以选择对每个中间结果执行.toSigned(32)
:
var result = ((someInt1 *
((((someInt2 * someInt3).toSigned(32) - someInt4).toSigned(32) -
(someInt5 * someInt6).toSigned(32))
.toSigned(32))
.toSigned(32)) -
someInt7)
.toSigned(32);
不是特别可读,编译到JavaScript时仍然不够,因为当结果表示为double时,即使两个32位整数乘以也可能会丢失精度。