我想将isize添加到usize中,并包括边界检查,以便结果不会溢出usize的边界。如何做到这一点?
isize
usize
wwodge7n1#
您可以使用isize::is_negative()、isize::wrapping_abs()、usize::checked_add()和usize::checked_sub()的组合。
isize::is_negative()
isize::wrapping_abs()
usize::checked_add()
usize::checked_sub()
const fn add(lhs: usize, rhs: isize) -> Option<usize> { if rhs.is_negative() { lhs.checked_sub(rhs.wrapping_abs() as usize) } else { lhs.checked_add(rhs as usize) } }
字符串为什么是isize::is_negative()和rhs < 0?在这种情况下,它不会改变任何东西,因为对文字的逻辑操作算作常量表达式。然而,虽然它被允许用于字面量,但通常是不允许的,因为traits方法不能是const。因此,如果你有一个 Package 类型,例如Foo(isize),那么在const上下文中就不允许说foo < Foo(0)。尽管如此,说foo.is_negative()是可能的,因为Foo仍然可以实现const fn is_negative()。
rhs < 0
const
Foo(isize)
foo < Foo(0)
foo.is_negative()
Foo
const fn is_negative()
foo.0 < 0
du7egjpx2#
Rustc 1.66+支持一些混合整数运算。请注意,这在mixed_integer_ops功能标志下以前不稳定。有了这个,你可以做:
fn main() { let x: usize = foo(); let y: isize = bar(); let (res, flag): (usize, bool) = x.overflowing_add_signed(y); // returns a (usize, bool) pair to indicate if overflow occurred println!("{x} + {y} = {res}, overflowed? {flag}"); }
字符串这些无符号整数的*_add_signed方法都接受一个有符号的参数,并返回一个无符号的结果。有几个变体,取决于你想如何具体处理溢出情况:
*_add_signed
overflowing_
checked_
Option
None
saturating_
MAX + 1 == MAX
MIN - 1 == MIN
wrapping_
有符号整数也有类似的方法,用于加法或减法,它们接受无符号参数并返回有符号结果,名为*_add_unsigned和*_sub_unsigned。(note:改编自我在https://stackoverflow.com/a/73153135/6112457的回答)
*_add_unsigned
*_sub_unsigned
pgky5nke3#
这样做的一种方法是使用如下函数:
fn signed_unsigned_add(x: usize, y: isize) -> usize { let (n, overflow) = x.overflowing_add(y as usize); if (y >= 0) ^ overflow { n } else { panic!( "signed + unsigned addition overflow: {} + {}", x, y, ) } }
字符串这利用了这样一个事实,即当从无符号数的Angular 来看时,这样的加法应该只在无符号数为负数时“溢出”(即表现出二进制补码行为),并且如果当数字为负数时不这样做,则这表明下溢。
3条答案
按热度按时间wwodge7n1#
您可以使用
isize::is_negative()
、isize::wrapping_abs()
、usize::checked_add()
和usize::checked_sub()
的组合。字符串
为什么是
isize::is_negative()
和rhs < 0
?在这种情况下,它不会改变任何东西,因为对文字的逻辑操作算作常量表达式。然而,虽然它被允许用于字面量,但通常是不允许的,因为traits方法不能是
const
。因此,如果你有一个 Package 类型,例如Foo(isize)
,那么在const上下文中就不允许说foo < Foo(0)
。尽管如此,说foo.is_negative()
是可能的,因为Foo
仍然可以实现const fn is_negative()
。foo.0 < 0
,但这不是我想表达的观点。*du7egjpx2#
Rustc 1.66+支持一些混合整数运算。请注意,这在mixed_integer_ops功能标志下以前不稳定。
有了这个,你可以做:
字符串
这些无符号整数的
*_add_signed
方法都接受一个有符号的参数,并返回一个无符号的结果。有几个变体,取决于你想如何具体处理溢出情况:overflowing_
,如上所示,返回一个pair,带有 Package 的结果和一个指示是否发生溢出的布尔标志。checked_
返回Option
,在溢出时为None
。saturating_
通过箝位到最大值和最小值(即MAX + 1 == MAX
,MIN - 1 == MIN
)来防止溢出。wrapping_
并没有解决你的用例--它只返回 Package 的结果,并不指示是否发生了溢出。有符号整数也有类似的方法,用于加法或减法,它们接受无符号参数并返回有符号结果,名为
*_add_unsigned
和*_sub_unsigned
。(note:改编自我在https://stackoverflow.com/a/73153135/6112457的回答)
pgky5nke3#
这样做的一种方法是使用如下函数:
字符串
这利用了这样一个事实,即当从无符号数的Angular 来看时,这样的加法应该只在无符号数为负数时“溢出”(即表现出二进制补码行为),并且如果当数字为负数时不这样做,则这表明下溢。