大整数运算中 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 的显式幂的主要内容,如果未能解决你的问题,请参考以下文章