如何在 Nim 中划分 int64?

How to divide int64 in Nim?

如何划分int64

let v: int64 = 100
echo v / 10

错误Error: type mismatch: got <int64, int literal(10)>

完整示例

import math

proc sec_to_min*(sec: int64): int = 
  let min = sec / 60 # <= error
  min.round.to_int

echo 100.sec_to_min

P.S.

并且,有没有一种方法可以安全地将 int64 转换为 int,因此结果将是 int 而不是 int64,并检查溢出。

在此 issue 中已经对 int64 division 进行了一些讨论,并且可能会对当前状态进行一些改进。来自上期:

  • stdlib 中没有 float division 在 int64 之间的一个很好的理由是它可能会导致精度损失,因此用户应该明确地将 int64 转换为float
  • 仍然,float divint 类型之间的转换存在于 stdlib
  • 在 64 位系统上 int int64(所以在 64 位系统中你有 division int64)

对于您的用例,我认为以下 (playground) 应该有效(最好使用 div 而不是执行 float division 然后四舍五入):

import math

proc sec_to_min*(sec: int64): int = sec.int div 60

echo 100.sec_to_min

let a = high(int64)
echo a.int  # on playground this does not raise error since int is int64
echo a.int32  # this instead correctly raises error

输出:

1
9223372036854775807
/usercode/in.nim(9)      in
/playground/nim/lib/system/fatal.nim(49) sysFatal
Error: unhandled exception: value out of range: 9223372036854775807 notin -2147483648 .. 2147483647 [RangeError]

P.S.: 正如你在上面看到的标准转换有范围检查

显然,在 int64 类型之间划分是非常危险的,因为它会引发一大群自行车脱落,但至少您可以创建自己的运算符:

proc `/`(x, y: int64): int64 = x div y

let v: int64 = 100
echo v / 10

proc `/`(x, y: int64): int64 = x div y

import math

proc sec_to_min*(sec: int64): int = 
  int(sec / 60)

echo 100.sec_to_min

关于 int64int 的转换,我不确定这是否有意义,因为大多数平台将 运行 int 作为 int64。但是当然你可以 compiling/running 在 32 位平台上,损失将是悲惨的,所以你仍然可以 运行 时间检查:

let a = int64.high

echo "Unsurprising but potentially wrong ", int(a)

proc safe_int(big_int: int64): int =
  if big_int > int32.high:
    raise new_exception(Overflow_error, "Value is too high for 32 bit platforms")
  int(big_int)

echo "Reachable code ", safe_int(int32.high)
echo "Unreachable code ", safe_int(a)

此外,如果您 运行 混淆了分钟、小时、天的转换,您可能需要查看 into distinct types 以避免将月数加到秒数(或以更安全的方式这样做) ).