在Rust中,BigInteger可以被截断为i32吗?

在Rust中,BigInteger可以被截断为i32吗?,rust,biginteger,Rust,Biginteger,在Java中,intValue()返回biginger实例的截断部分。我在Rust中编写了一个类似的程序,但它似乎没有截断: extern crate num; use num::bigint::{BigInt, RandBigInt}; use num::ToPrimitive; fn main() { println!("Hello, world!"); truncate_num( BigInt::parse_bytes(b"423445324324324

在Java中,
intValue()
返回
biginger
实例的截断部分。我在Rust中编写了一个类似的程序,但它似乎没有截断:

extern crate num;

use num::bigint::{BigInt, RandBigInt};
use num::ToPrimitive;

fn main() {
    println!("Hello, world!");
    truncate_num(
        BigInt::parse_bytes(b"423445324324324324234324", 10).unwrap(),
        BigInt::parse_bytes(b"22447", 10).unwrap(),
    );
}

fn truncate_num(num1: BigInt, num2: BigInt) -> i32 {
    println!("Truncation of {} is {:?}.", num1, num1.to_i32());
    println!("Truncation of {} is {:?}.", num2, num2.to_i32());
    return 0;
}
我从中得到的结果是

你好,世界!
423445324324的截断为无。
22447的截断是一些(22447)。

我怎样才能做到这一点?我是否应该尝试转换为
字符串
,然后手动截断?这是我最后的办法。

大整数不能自然地截断成小整数。要么它合适,要么你必须决定你想要什么价值

您可以这样做:

println!("Truncation of {} is {:?}.", num1, num1.to_i32().unwrap_or(-1));

但是,当返回的选项不包含任何值时,应用程序逻辑可能会指定所需的行为。

Java返回整数的最低32位。这可以通过按位AND操作
x&0xffffffff
完成。A不支持按位操作,但您可以先将其转换为一个
BigUint
,以执行此类操作

fn截断biguint到u32(a:&biguint)->u32{
使用std::u32;
让mask=BigUint::from(u32::MAX);
(a&mask).to_u32().unwrap())
}
BigInt
转换为
BigInt
仅当它不是负值时才会成功。如果
BigInt
为负(-x),我们可以找到其绝对值(x)的最低32位,然后对结果求反

fn将_bigint_截断为_u32(a:&bigint)->u32{
使用num_traits::Signed;
let was_negative=a.is_negative();
设abs=a.abs().to_biguint().unwrap();
设mut truncated=truncate_biguint_to_u32(&abs);
如果你是负数{
截断。包装_neg()
}否则{
截断的
}
}

如果您需要有符号的数字,您可以使用
truncate_bigint_to_u32(a)as i32


还有一种方法可用于提取字节并将其直接解码为原始整数:

fn截断\u bigint\u到\u u32\u慢(a:&bigint)->u32{
设mut bytes=a.to_signed_bytes_le();
字节。调整大小(4,0);

字节[0]作为u32 |(字节[1]作为u32)什么是“截断”对于i32中的大整数拟合?您可能应该检查该选项是否包含值,并仅在这种情况下使用它。为什么要使用此功能???您到底想要什么?请使用不同的情况和您的用例解释预期结果。否则,您的问题太广泛。具体而言,Java指定了:这种转换类似于Java语言中定义的从long到int的缩小原语转换™ 语言规范:如果这个BigInteger太大,无法放入整型,则只返回低阶32位。“@DenysSéguret我发表了我的评论,这样人们就可以知道等效的行为需要是什么。鉴于该行为被明确定义为与对整型进行长整型时的行为类似,它不是”实现泄漏",这是一个深思熟虑的设计选择。如果你不想要这种类型的行为,你可以使用它,如果值超出int的范围,就会抛出异常。谢谢@kennytm。如果没有自然截断,这将是我想要的另一种方法。我正在从Java切换到Rust,因此与Java形成对比。谢谢@Denys,但我确实需要Java中的行为,如果不能满足所有情况,我宁愿不尝试使用
to_i32
。无论如何,当返回的选项不包含值时,我必须使用其他逻辑。
println!("Truncation of {} is {:?}.", num1, num1.to_i32().unwrap_or(std::i32::MAX));