首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Rust的u64需要一个u32?

为什么Rust的u64需要一个u32?
EN

Stack Overflow用户
提问于 2019-07-19 21:02:07
回答 2查看 3.1K关注 0票数 11

为什么罗斯特的u64本原需要一个u32指数?

代码语言:javascript
复制
error[E0308]: mismatched types
  --> src/protagonists.rs:13:25
   |
13 |         return root.pow(self.secret) % prime;
   |                         ^^^^^^^^^^^ expected u32, found u64
help: you can convert an `u64` to `u32` and panic if the converted value wouldn't fit

https://doc.rust-lang.org/std/primitive.u64.html#pow.v

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-20 00:09:27

为什么大多数操作都需要相同类型的操作数?

我们很容易看到2i32 + 2i64应该是4i64,但是对于CPU来说,2i322i64是完全不同的,完全不相关的东西。CPU内部的+实际上只是一个硬件,它通常支持两个32位输入或两个64位输入,但不支持一个32位输入和一个64位输入。因此,为了将i32添加到i64中,必须将较短的数字进行符号扩展,然后才能将这两个值插入到ALU。

对于大多数整数和浮点算术运算,通常也是如此:必须对不匹配的类型进行转换才能完成数学运算。在C中,编译器通常将两个操作数提升为可以表示两个值的最小类型;根据上下文的不同,这些隐式转换称为“整数提升”或“通常的算术转换”。然而,在Rust中,编译器通常只知道相同类型的操作,因此您必须通过决定如何转换操作数来选择所需的操作类型。喜欢锈病的人一般认为这是一件好事。

为什么这不适用于u64::pow

并非所有算术操作,即使是在硬件中实现的运算,都接受相同类型的参数。在硬件中(虽然不是在LLVM中),shift指令常常忽略shift参数的更高位(这就是为什么在C移位中调用的整数大小大于未定义行为的原因)。LLVM提供了将浮点数提高到整数幂的使用说明

这些操作是不同的,因为输入是不对称的,设计者常常利用这些不对称来使硬件变得更快、更小。但是,在u64::pow的情况下,它不是用硬件指令它只是用朴素的锈写的实现的。考虑到这一点,很明显,要求指数为u64是非常不必要的:正如施韦恩的回答所指出的那样,u32非常有能力包含u64可以被提升到的所有可能的幂,因此额外的32位是毫无意义的。

好吧,为什么u32

最后一句同样适用于u16,甚至u8 -- u64不能包含pow(2, 255),因此使用u32似乎同样浪费。然而,也有一些实际的考虑。许多调用约定在寄存器中传递函数参数,因此在32位(或更大)平台上,您将不会看到比这更小的任何好处。许多CPU也不支持本地8位或16位算术,所以这个参数无论如何都必须进行符号扩展,以实现我之前链接到的逐平方运算算法。简而言之,我不知道为什么选择u32,但是这样的事情可能已经被考虑到决策中了。

“公约”的规则在某种程度上受到历史的制约,并支持广泛的历史硬件。生锈只针对LLVM,所以编译器不需要担心底层硬件是否有一个原始的8位add指令;它只是发射add,让LLVM担心它是否会被编译成一个原始指令或模拟32位指令。这就是为什么char + char在C中是int,而i8 + i8在Rust中是i8的原因。

票数 10
EN

Stack Overflow用户

发布于 2019-07-19 22:01:36

这是有根据的猜测。

考虑一下,将u64提升到u32的能力已经超过了任何u64。例如,如果我们取2(最小可能的有效u64),并将其提高到2^10或1024,我们得到的东西比u64大。

179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216

没有必要允许一个更大的指数,它只是意味着一个更昂贵的计算,更有可能溢出。

如果u64不能安全地降级为u32,那么它绝对不能作为指数使用。出于同样的原因,u128.pow也只取u32指数。

注意:有pow来检测可能的溢出。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57119562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档