有没有办法在不使用BigInt的情况下打印n ^ 1000的值?一直在思考使用某种转换逻辑的方法,但还没有能够提出一些好的东西。
答案 0 :(得分:1)
你当然可以这样做,我推荐它作为练习。除此之外,没有什么理由以现有BigInteger实现的语言实现它。
如果您正在寻找练习,那么使用支持BigIntegers开箱即用的语言进行练习真的很有帮助。这样你就可以逐步用自己的操作取代BigInteger操作,直到没有什么可以替换。
BigInteger库通常使用相同基元类型的数组(如byte或int)表示大于最大基元的值。这里是我编写的一些Python,用于模拟无符号字节(UByte)和无符号字节列表(BigUInt)。任何具有多个UBytes的BigUInt都将索引0视为最重要的字节,使其成为一个大端表示。反之亦然。
class UByte:
def __init__(self, n=0):
n = int(n)
if (n < 0) or (n >= 255):
raise ValueError("Expecting integer in range [0,255).")
self.__n = n
def value(self):
return self.__n
class BigUInt:
def __init__(self, b=[]):
self.__b = b
def value(self):
# treating index 0 as most-significant byte (big endian)
byte_count = len(self.__b)
if byte_count == 0:
return 0
result = 0
for i in range(byte_count):
place_value = 8 * (byte_count - i - 1)
byte_value = self.__b[i].value() << place_value
result += byte_value
return result
def __str__(self):
# base 10 representation
return "%s" % self.value()
上面的代码并没有完全符合您的要求。 BigUInt#value
的几个部分依赖于Python的内置BigIntegers,例如,即使byte_value
非常大,左移到计算place_value
也不会溢出。在较低级别的机器代码中,每个值都有固定的位数,左移不小心会导致信息丢失。同样,更新+=
的{{1}}操作最终会因为低级代码中的相同原因而溢出,但Python会为您处理。
请注意,result
是通过调用__str__
来实现的。绕过Python神奇的一种方法是重新实现value()
,这样就不会调用__str__
。弄清楚如何将二进制数转换为基数为10的数字。完成后,您只需拨打value()
value()
__str__
实施return int(self.__str__())
以下是上述代码的一些示例测试。在您重新编写代码时,它们可能有助于进行健全性检查。
ten_as_byte = UByte(10)
ten_as_big_uint = BigUInt([UByte(10)])
print "ten as byte ?= ten as ubyte: %s" % (ten_as_byte.value() == ten_as_big_uint.value())
three_hundred = 300
three_hundred_as_big_uint = BigUInt([UByte(0x01), UByte(0x2c)])
print "three hundred ?= three hundred as big uint: %s" % (three_hundred == three_hundred_as_big_uint.value())
two_to_1000th_power = 2**1000
two_to_1000th_power_as_big_uint = BigUInt([UByte(0x01)] + [UByte() for x in range(125)])
print "2^1000 ?= 2^1000 as big uint: %s" % (two_to_1000th_power == two_to_1000th_power_as_big_uint.value())
编辑:有关所需内容的更好的低级别说明,请参阅From NAND to Tetris课程的第2章。该章中的项目是实现一个16位ALU(算术逻辑单元)。如果然后扩展ALU以输出溢出位,则可以将任意数量的这些ALU链接在一起,以处理基于任意大输入数的基本计算。
答案 1 :(得分:0)
将一个小数字 - 一个适合普通整数变量 - 提升到一个高功率是最容易实现的大整数运算之一,它经常被用作让人们发现一些大整数数学实现原则的任务
一个很好的讨论 - 包括C中的许多不同的例子 - 在代码审查的主题Sum of digits in a^b中。 My contribution there显示了如何通过重复平方来进行快速取幂,使用std::vector<uint32_t>
作为一种假冒&#39;大整数。但是在这个主题中甚至有更简单的解决方案,只需选择。
测试C / C ++大整数代码而不必寻找大型整数库的简单方法是在Visual C ++(Express)中将代码编译为托管C ++,这样您就可以访问.NET BigInteger类:
#using "System.Numerics.dll"
using System::Numerics::BigInteger;
BigInteger n = BigInteger::Parse("123456789");
System::Console::WriteLine(n.Pow(1000));