大整数运算中 2 的显式幂

Posted

技术标签:

【中文标题】大整数运算中 2 的显式幂【英文标题】:Explicit powers of 2 in biginteger operations 【发布时间】:2014-04-07 08:37:54 【问题描述】:

我有一段代码类似于(vb.net 或 c#“语言”无关紧要):

 Dim Counter As BigInteger = 0
 Serial = BigInteger.DivRem(Serial, 4, Counter)
 CountersList.Add(CInt(Counter))

由于我用非常大的正整数(几百位数)将其中的许多除以 4,并且在收到一些“内存不足异常”后,我又去阅读了文档。

在移位运算符page 中,我可以阅读: “不支持自定义运算符的语言可以通过乘法执行按位左移操作 BigInteger.Pow(2, shift) 的值。"

所以我认为上面的代码也许可以改进这种方式(明确表示我除以 2 的幂):

Dim Counter As BigInteger = 0
Serial = BigInteger.DivRem(Serial, BigInteger.Pow(2, 2), Counter)
CountersList.Add(CInt(Counter))

我的问题。

一般来说,显式使用 BigInteger.Pow() 是否有任何优势,以便 (?) 编译器知道它可以执行移位,而不是乘法/除法?

在我的具体情况下,我需要除以 4,并得到结果和余数,最好的方法是什么?

【问题讨论】:

IIRC, Pow 对负数的作用不同。 【参考方案1】:

一般来说,显式使用 BigInteger.Pow() 是否有任何优势,以便 (?) 编译器知道它可以执行移位,而不是乘法/除法?

CIL(.NET 语言后面的中间语言,即汇编代码)中不支持BigInteger,所以不,编译器无法优化它。 (除非它对BigInteger 有一些非常具体的支持,以便理解它可以将“除以4”替换为“右移两位”等。)

在我的具体情况下,我需要除以 4,并得到结果和余数,最好的方法是什么?

您可以使用And 的序列来获得余数,并使用>> 来执行除法,例如:

Dim Remainder as BigInteger = Serial And New BigInteger(3)
Serial = Serial >> 2

(注意:抱歉可能出现语法错误,VB 不是我的语言。)

但是,我不认为OutOfMemoryException 的来源是这些琐碎的操作。检查期望的堆栈跟踪以了解它首先发生的位置。

【讨论】:

谢谢 Ondrej,这很有趣。你能帮我理解你得到剩余部分的方法吗?这是在班次前“抓住”两个位的方法吗? 二进制中的余数可以是 00、01、10 和 11,用于除以四。三是二进制的 11,所以 AND 得到余数。如果您将商和余数保留在内存中,并且做的足够多,您可能仍然会遇到内存不足的问题。 @dbasnett 谢谢。我想这是因为我们使用 11 作为前 2 位的小端格式。但是我注意到,无论如何,即使大整数中的位实际上向左移动(我认为),这种移动还是在语言级别“向右”移动。 字节顺序纯粹是 CPU 中的实现问题。只要您将给定的一组字节解释为单个整数,它就与按位运算无关。 @Ondrej 是的,你是对的。感谢您的指导性回答:-)

以上是关于大整数运算中 2 的显式幂的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的显式构造函数会为我的转换运算符创建这种歧义?

智能转换与 KOTLIN 中的显式转换有何不同

我可以内联指定我的显式类型比较器吗?

基于Java的大整数运算的实现(加法,减法,乘法)学习笔记

Swift 2 中的显式老式错误处理

PHP中任意大整数的算术运算