如何在 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
关于 int64
到 int
的转换,我不确定这是否有意义,因为大多数平台将 运行 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 以避免将月数加到秒数(或以更安全的方式这样做) ).
如何划分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
关于 int64
到 int
的转换,我不确定这是否有意义,因为大多数平台将 运行 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 以避免将月数加到秒数(或以更安全的方式这样做) ).