如何在Rust中将有符号整数添加到无符号整数,检查无符号溢出?

如何在Rust中将有符号整数添加到无符号整数,检查无符号溢出?,rust,unsigned,signed,Rust,Unsigned,Signed,我想将isize添加到usize中,并包含边界检查,以便结果不会溢出usize的边界。如何做到这一点?您可以使用、和的组合 const-fn-add(左侧:usize,右侧:isize)->选项{ 如果rhs.为负(){ 左勾选(右勾选)将abs()包装为usize }否则{ 左侧已选中\u添加(使用右侧) } } 为什么vsrhs

我想将
isize
添加到
usize
中,并包含边界检查,以便结果不会溢出
usize
的边界。如何做到这一点?

您可以使用、和的组合

const-fn-add(左侧:usize,右侧:isize)->选项{
如果rhs.为负(){
左勾选(右勾选)将abs()包装为usize
}否则{
左侧已选中\u添加(使用右侧)
}
}

为什么vs
rhs<0
?在这种情况下,它不会改变任何东西,因为对文本的逻辑操作也会被计算在内

但是,虽然允许使用文本,但通常不允许使用,因为traits方法不能是
const
。因此,如果您有一个包装类型,例如
Foo(isize)
,那么它就不允许在常量上下文中说
Foo
。尽管如此,可以说
foo.is_negative()
,因为
foo
仍然可以实现
常量fn is_negative()


是的,你仍然可以说
foo.0<0
,但这不是我想说的重点。

你可以使用,和的组合

const-fn-add(左侧:usize,右侧:isize)->选项{
如果rhs.为负(){
左勾选(右勾选)将abs()包装为usize
}否则{
左侧已选中\u添加(使用右侧)
}
}

为什么vs
rhs<0
?在这种情况下,它不会改变任何东西,因为对文本的逻辑操作也会被计算在内

但是,虽然允许使用文本,但通常不允许使用,因为traits方法不能是
const
。因此,如果您有一个包装类型,例如
Foo(isize)
,那么它就不允许在常量上下文中说
Foo
。尽管如此,可以说
foo.is_negative()
,因为
foo
仍然可以实现
常量fn is_negative()


是的,您仍然可以说
foo.0<0
,但这不是我想说的重点。

一种方法是使用如下函数:

fn signed\u unsigned\u add(x:usize,y:isize)->usize{
设(n,溢出)=x.overflowing_加上(y为usize);
如果(y>=0)^溢出{
N
}否则{
恐慌(
“有符号+无符号加法溢出:{}+{}”,
x,,
Y
)
}
}

这利用了这样一个事实,即当从无符号数的角度来看,这种加法仅在无符号数为负数时“溢出”(即,图表2的补码行为),如果在数字为负数时不溢出,这表示下溢。

一种方法是使用如下功能:

fn signed\u unsigned\u add(x:usize,y:isize)->usize{
设(n,溢出)=x.overflowing_加上(y为usize);
如果(y>=0)^溢出{
N
}否则{
恐慌(
“有符号+无符号加法溢出:{}+{}”,
x,,
Y
)
}
}

这充分利用了这样一个事实,即从无符号数的角度来看,当无符号数为负数时,这种加法只会“溢出”(即,表现出2的补码行为),如果在数字为负数时不溢出,则表示下溢。

jc,有理由选择
is_negative()
over
<0
?如果
rhs
isize::MIN
,这个问题不会溢出吗?使用
x<0
也可以,是的,它溢出了,我已经更新了答案,使用
wrapping_abs()
@kmdreko我已经添加了一些上下文来解释为什么
是否定的()
vs
<0
@goose121 No.isize::MIN是0b1000..000,
-(isize::MIN+1)
是0b0111..1111所以
isize::MIN as usize==(isize::MIN+1)as usize+1
.jc,有理由选择
是否定的()
over
<0
?如果
rhs
isize::MIN
,这个问题不会溢出吗?使用
x<0
也可以,是的,它溢出了,我已经更新了答案,使用
wrapping_abs()
@kmdreko我已经添加了一些上下文来解释为什么
是否定的()
vs
<0
@goose121号isize::MIN是0b1000..000,
-(isize::MIN+1)
是0b0111..1111所以
isize::MIN as usize==(isize::MIN+1)as usize+1