【大数算法】( 十进制整数四则运算) 十进制运算与二进制比较与思考

  这两天心血来潮, 想熟悉下Eclipse。 偶是写Python的, 一般都在Ubuntu上用VIM做编辑器, PDB做调试工具, 自带的python2.7解释器, git做版本控制。 用着挺爽, 也就没有搞啥IDE, 但是最近发现要做大项目或工程的话, IDE啥的还是很有必要的。

  几乎把所有支持Py的IDE都尝试过了, eric用着特别扭(还是比较习惯VIM的便捷操作),  要Python的自动补全居然还要用户自己配置api文件。。 居然还敢自称专业Python IDE..太让人失望了。 wing IDE试用了下,挺不错的。。 但是要收费。。 想着在Linux环境下还要用破解软件就觉得特憋屈。 vim -> configure -> make -> make install已成习惯,自然不堪其辱,果断放弃了。。 IDLE顶多算个编辑器。 还没VIM功能强大, 完全感觉不到可以拿来做大项目。。 

  最后还是选择了Eclipse + Pydev + Vrapper Eclipse强大的工程管理和自动补全,doc功能 + VIM的全键盘式操作 = 犀利。。

  一直坚持写些简单算法练手, 逻辑, coding 双丰收, 咧呵呵。

正式开始

加法:

   先写了测试代码:

      

#!/usr/bin/env python
from hugeoperation import HugeOperation
import unittest

class TestHugeOperation(unittest.TestCase):

	def setUp(self):
		self.testobj = HugeOperation()
		self.testdata = {}
		self.testdata['add'] = [
				   ['2000', '1000', '1000'],
				   ['0','0','0'],
				   ['1', '0', '1'],
				   ['0', '1', '-1'],
			       ['337618', '3495', '334123'],
				   ['-219', '-98', '-121'],
				   ['3', '-32', '35'],
                   ['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'],
				   ['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512',\
				   '1125899906842624' ]
								]
		
		
	def test_add(self):
		for i in self.testdata['add']:
			self.assertEqual(i[0], self.testobj.huge_add(i[1], i[2]))
			print i,
			print '		Passed!\n'


if __name__=='__main__':
	unittest.main()

    就经验来说,四则里面最基本的应该是加法,所以就先设计好加法的测试用列, 给了9组测试数据, 肯定没考虑全面, 比如边界值测试,异常输入什么的都没设计。。 毕竟只是练手的东西,要求不要太严格了,呵呵


然后开始设计算法:

   计算机指令的运算是基于位的二进制运算, 大学老师教过整型有表示范围, 就算用长整型也是有限的,具体限制与不同语言和不同系统平台有关。不借助库的话是无法实现超级大数运算的。 如计算2^258 + 2^512 用一般的整型运算肯定是无法实现的。

   我使用字符串来存储两个数,然后用一个字符串来存储结果。

   加法比较简单, 从低位起逐位相加,除10取余与进位寄存器相加便是该位的值, 进位只有0和1两种状态。

   实现代码如下:


#add fun
def _add_operate(self, anum, bnum):
		carry = 0
		rdigit = 0
		rnum = []
		while anum or bnum:
			adigit = 0
			bdigit = 0
			if anum:
				adigit=anum.pop()
			if bnum:
				bdigit=bnum.pop()	
			rdigit = adigit + bdigit + carry
			carry = rdigit / 10
			rdigit = rdigit % 10	
			rnum.append(str(rdigit))
		if carry:
			rnum.append('1')
		rnum.reverse()
		result = rnum
		return result


  该函数输入是两个整形列表,分别顺序存储了两个加数。 输出是一个顺序存储了计算结果的字符型列表 (如果出于对输入兼容性的角度考虑, 可以在函数最开始对列表元素做强制转型处理, 这里为了简洁我没做。)

有两个地方需要注意: 1. 当算到最后一位仍有进位时, 需要把进位添加到结果的最高位, 当然,也只可能是1. 

                                  2. 进位寄存器使用后要归零, 这个比较容易出bug。

    但是一般来说读入的数据会是两个字符串, 如我们测试用列设计的那样, 所以需要一个对输入初始化的函数, 将字符串转换为列表:

def _huge_init(self, a):
		'''_huge_init(string)
			return list[list[sign],list[num]]
		'''
		num = []
		sign = 0
		if a[0] == '-':
			sign = 1
			for i in a[1:]:
				num.append(int(i))
		else:
			for i in a:
				num.append(int(i))
		return list([sign,num])

该函数是将输入的字符串列表化, 并且要考虑首位是否有负号。 该函数输入是一个字符串, 输出是一个二维列表, 其中第一维存储了符号, 第二维存储了无符号的整型列表

有了这两个函数依旧不够。。 这两个都是功能函数, 我们还差一个接口函数,这个接口函数会调用这两个功能函数完成运算并负责输出。 首先确定该函数的输入为两个字符串, 输出为结果字符串。 然后再对其中代码进行设计如下:

def huge_add(self, a, b):
		'''huge_add(string,string)
			return string
		'''
		asign = self._huge_init(a)[0]
		anum = self._huge_init(a)[1]
		bsign = self._huge_init(b)[0]
		bnum = self._huge_init(b)[1]
		#switcher: 0 => +&+ 1=> -&+ 2=>+&- 3=>-&-
		switcher = asign | bsign << 1
		if switcher == 0: 
			result = ''.join(self._add_operate(anum, bnum))
		if switcher == 1:
			result = ''.join(self._sub_operate(bnum, anum))
		if switcher == 2:
			result = ''.join(self._sub_operate(anum, bnum))
		if switcher == 3:
			result = '-' + ''.join(self._add_operate(anum, bnum))
		return result

     该函数先是调用init函数对输入列表化,然后根据符号位控制输出。 其中调用到暂时还没提到的_sub_operate, 因为相异符号的加法就是一个减法运算, 同样,减法运算也可以转化为相异符号的加法运算。 所以后面大家会发现, 减法的接口函数其实是依赖于加法接口函数的囧。。 


     但是必须强调, 减法和加法的算法是不同的。 而计算机的二进制算法是用补码来表示被减数, 然后再做加法。 看似只用了一个算法就实现了加和减,但是求补也是一个算法嘛。。只是求补的算法远比我的减法算法简单效率高,呵呵

     原本我也是想等到写减法接口的时候再实现减法函数的,但是写了才知道这个先后顺序。。 要实现带符号的加法运算就必须先把减法函数写了T_T

   下面是我的减法运算函数(不是减法接口函数):


#subtraction fun
	def _sub_operate(self, anum, bnum):
		carry = 0
		rdigit = 0
		rsign = 0
		rnum = []
		if len(bnum) > len(anum) or len(anum) == len(bnum) and \
		 anum < bnum:
			tmp = anum
			anum = bnum
			bnum = tmp
			rsign = 1
		while anum:
			adigit = 0
			bdigit = 0
			if anum:
				adigit = anum.pop()
			if bnum:
				bdigit = bnum.pop()
			rdigit = adigit - bdigit - carry
			if rdigit < 0:
				rdigit = rdigit + 10
				carry = 1	
			else:
				carry = 0
			rnum.append(str(rdigit))
		if rnum[-1] == '0' and len(rnum)-1:
			rnum = rnum[0:-1]
		if rsign:
			rnum.append('-')
		rnum.reverse()
		result = rnum
		return result



减法先对减数和被减数做了下大小比较, 把大数换到被减数位置去,这样既可以减少逐位相减次数(减的次数是由减数位数决定的,所以减数越短减的次数越少)又可以将可能带符号的减法换为无符号减法运算(大数减小数必然为正)。 而根据减法法则, 交换减数被减数只需要在结果填一个负号便可。 所以当发生交换时符号标志(rsign)置1.

然后便是小学学的逐位相减,不足借位。 借位寄存器用完记得清零就好了。。

结果要除去高位的0,因为高位0 是没有意义的, 但需要特别处理结果为0的状况。 根据符号标志设置一下符号便搞定咯。

    接着比较了下二进制加法与我写的十进制加法,发现两个的计算方法是 一样的,都是逐位累加,然后用进位寄存器来存储进位。 看来加法确实是最简单的啊

    减法上二进制就厉害多了。因为是用加补码,溢出舍弃的方式做减法, 最高位做符号位时依然适用, 少了很多符号换来换去的麻烦。

    补码算法明显比这个减法算法简单, 按位取反再加一。 最后在做一次加法。 三个运算符就搞定咯。。

测试也顺利通过了:

['2000', '1000', '1000'] 		Passed!

['0', '0', '0'] 		Passed!

['1', '0', '1'] 		Passed!

['0', '1', '-1'] 		Passed!

['337618', '3495', '334123'] 		Passed!

['-219', '-98', '-121'] 		Passed!

['3', '-32', '35'] 		Passed!

['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'] 		Passed!

['10429624198832568761694441924656016184583518.17556959360325703910069443225478829519465806299136', '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512', '1125899906842624'] 		Passed!


----------------------------------------------------------------------
Ran 1 test in 0.033s

OK


减法:

先写测试用列:

#!/usr/bin/env python
from hugeoperation import HugeOperation
import unittest

class TestHugeOperation(unittest.TestCase):

	def setUp(self):
		self.testobj = HugeOperation()
		self.testdata = {}
		self.testdata['add'] = [
				   ['2000', '1000', '1000'],
				   ['0','0','0'],
				   ['1', '0', '1'],
				   ['0', '1', '-1'],
			       ['337618', '3495', '334123'],
				   ['-219', '-98', '-121'],
				   ['3', '-32', '35'],
                   ['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'],
				   ['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512',\
				   '1125899906842624' ]
								]
		
		self.testdata['sub'] = [['0', '1', '1'],
					['1','1','0'],
					['-1','0','1'],
					['23','45','22'],
					['13','5','-8'],
					['26','-3','-29'],
					['-2582249878086908587416174429825207663772263512260779234709013859305998087116852093665853482099976886055025678701140377600',\
					'2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776',\
					'2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376']
								]
		

		
	def test_add(self):
		for i in self.testdata['add']:
			self.assertEqual(i[0], self.testobj.huge_add(i[1], i[2]))
			print i,
			print '		Passed!\n'

	def test_sub(self):
		for i in self.testdata['sub']:
			self.assertEqual(i[0], self.testobj.huge_sub(i[1], i[2]))
			print i,
			print '		Passed!\n'
	

if __name__=='__main__':
	unittest.main()


   加法函数,减法函数,初始化函数都有了,减法接口实现还难么? 不多说了,大家请看:

#subtraction interface
	def huge_sub(self, a, b):
		if b[0] == '-':
			b = b[1:]
		else:
			b = '-' + b
		result = self.huge_add(a,b)
		return result

对。。就是这么Easy。。

  测试通过:

['2000', '1000', '1000'] 		Passed!

['0', '0', '0'] 		Passed!

['1', '0', '1'] 		Passed!

['0', '1', '-1'] 		Passed!

['337618', '3495', '334123'] 		Passed!

['-219', '-98', '-121'] 		Passed!

['3', '-32', '35'] 		Passed!

['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'] 		Passed!

['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512', '1125899906842624'] 		Passed!

['.0', '1', '1'] 		Passed!

['1', '1', '0'] 		Passed!

['-1', '0', '1'] 		Passed!

['23', '45', '22'] 		Passed!

['13', '5', '-8'] 		Passed!

['26', '-3', '-29'] 		Passed!

['-258224987808690858741617442982520766377226351226077923470901385930.5998087116852093665853482099976886055025678701140377600', '2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776', '2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376'] 		Passed!


----------------------------------------------------------------------
Ran 2 tests in 0.042s

OK

乘法:
  
写算法之前先添加测试用列:
#!/usr/bin/env python
from hugeoperation import HugeOperation
import unittest

class TestHugeOperation(unittest.TestCase):

	def setUp(self):
		self.testobj = HugeOperation()
		self.testdata = {}
		self.testdata['add'] = [
				   ['2000', '1000', '1000'],
				   ['0','0','0'],
				   ['1', '0', '1'],
				   ['0', '1', '-1'],
			       ['337618', '3495', '334123'],
				   ['-219', '-98', '-121'],
				   ['3', '-32', '35'],
                   ['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'],
				   ['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512',\
				   '1125899906842624' ]
								]
		
		self.testdata['sub'] = [['0', '1', '1'],
					['1','1','0'],
					['-1','0','1'],
					['23','45','22'],
					['13','5','-8'],
					['26','-3','-29'],
					['-2582249878086908587416174429825207663772263512260779234709013859305998087116852093665853482099976886055025678701140377600',\
					'2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776',\
					'2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376']
								]
		
		self.testdata['mul'] = [
					['12','3','4'],
					['0','32','0'],
					['-0','-32','0'],
					['-54612','123','-444'],
					['54612','-123','-444'],
					['603822', '641', '942'],
					['1831650372496', '2341234', '782344'],
					['1007515750397959314', '1231231923', '818298918'],
					['324518553658426726783156020576256','18014398509481984',\
					'18014398509481984'],
					]
		
	def test_add(self):
		for i in self.testdata['add']:
			self.assertEqual(i[0], self.testobj.huge_add(i[1], i[2]))
			print i,
			print '		Passed!\n'

	def test_sub(self):
		for i in self.testdata['sub']:
			self.assertEqual(i[0], self.testobj.huge_sub(i[1], i[2]))
			print i,
			print '		Passed!\n'
	
	def test_multiple(self):
		for i in self.testdata['mul']:
			self.assertEqual(i[0], self.testobj.huge_multip(i[1], i[2]))
			print i,
			print '		Passed!\n'

if __name__=='__main__':
	unittest.main()


 然后开始设计算法:
   小学学过做乘法是逐位相乘,然后累加。 最后的累加是个阵列式。 累加我们可以调用之前设计的无符号加法函数来完成。 所以在计算机上乘法器是基于加法器一说便是这么由来的。 先来看代码:

#multiplication fun
	def _multi_poperate(self, anum, bnum):
		carry = 0
		rnum = []
		strrnum = []
		accnum = []
		acclist = []
		#Switch the short num to multiplicator
		if len(anum) < len(bnum):
			tmpnum = anum
			anum = bnum
			bnum = tmpnum
		#逐位相乘,乘积的阵列式放在二维列表acclist中, 
		#acclist的下标整好可以标识该行数据的进位。
		while bnum:
			adigit = 0
			bdigit = 0
			bdigit=bnum.pop()	
			for adigit in anum[::-1]:
				product = (bdigit * adigit + carry) % 10
				carry = (bdigit * adigit + carry)/10
				accnum.append(product)
			if carry:
				accnum.append(carry)
				carry = 0
			acclist.append(accnum[::-1])	
			accnum = []
		t = 1;
		rnum = acclist[0];
		#累加运算, 注意由于输出是字符型列表,要实现累加需要对每次输出进行整型转型
		while t < len(acclist):
			for i in range(0,t):
				acclist[t].append(0)
				b = acclist[t]
			accnum = self._add_operate(rnum,b)
			for i in accnum:
				rnum.append(int(i))
			t +=1
		#去除高位多余的0
		zerosign = 0	
		for i in rnum:
			if i:
				zerosign = 1
			if zerosign:
				strrnum.append(str(i))
		if not strrnum:
			strrnum = ['0']
		result = strrnum
		return result


    PS:中文注释是写文章的时候才加的。。之前觉得逻辑很简单,没有必要
    首先做的依然是根据位数交换乘数被乘数位置,减少阵列式累加次数。 之后是逐位相乘后放入阵列式中. 注意算乘法时最后有进位的话记得把进位进上去,并把进位寄存器清零。 每次乘出的积会倒序,所以需要对列表正序列化。
然后对阵列做累加,每次取阵列式里面的数时要根据下标补零 (十进制的移位??)
最后去除高位多余的0, 完成。

与二进制相比较算法大抵相当,都是做阵列式累加。 只是二进制乘法的逐位相乘就是一个左移位操作,非常便捷(因为乘数要么为0,要么为1.。 为0时该行直接添零,为一时根据该位位置直接移位就好了) 。 串行乘法器所做的也就是‘移位-累加’操作罢了。 后来出现的并行乘法器算法也是一样的, 不过借由全加器实现了接受3个输入(之前该位的累加结果+阵列值+进位值 ) 和提供两个输出(进位值+累加结果) 。 这样便可以将执行效率提高N倍(理论值, N 为被乘数位宽)。 但是归根而言依旧是逐位相乘,再阵列累加的方法,只是将累加操作并发了而已

最后是乘法的接口函数:
  符号判断很简单,符号位求异或。。 计算机做乘法时也是这么干的。。
def huge_multip(self, a, b):
		asign = self._huge_init(a)[0]
		anum = self._huge_init(a)[1]
		bsign = self._huge_init(b)[0]
		bnum = self._huge_init(b)[1]
		#rsign: 0 -> + ; 1 -> -
		rsign = asign ^ bsign
		result = ''.join(self._multi_poperate(anum, bnum))
		if rsign:
			result = '-' + result
		return result

测试结果不发了。。 等除法做完一起贴上来。。

除法:

   除法这个才是最有意思的。 二进制做除法相当爽啊, 直接做‘差-》移位’就搞定了。 因为商只可能是0和1。 按照除法的法则,我们也可以从高位开始做差,然后移位。 但是我在这里使用了另一种方法实现了类似操作:

def _div_operate(self, anum, bnum):
		trynum = [1]
		result = []
		n = 0
		# if divider is bigger than dividend, return '0'
		if len(anum) < len(bnum) or len(anum) == len(bnum) and \
		anum[0] < bnum[0]:
			return ['0']
		else:
			#Use the diff of tow number's length to ensure the try number's bit
			bitdiff = len(anum) - len(bnum)
			#If the first number of divider is bigger than dividend, try number's bit -1
			if anum[0] < bnum[0]:
				n = 1
			#Initial try number as a '10000' like number
			for i in range(n, bitdiff):
				trynum.append(0)
			#Use try number to multiply the dividend and compare with divider
			for i in range(0,len(trynum)):
				k = 1
				#If result number is bigger than divider, 
				#break out and set the littler bit to 1
				#If result is at the last bit, do not set the littler bit and break out.
				while 1:
					if k == 10:
						if i < len(trynum)-1:
							trynum[i] = 9
							break
						else:
							break
					strtryresult = self.huge_multip(bnum, trynum)
					tryresult = []
					for n in strtryresult:
						tryresult.append(int(n))
					if len(tryresult) > len(anum) or len(tryresult) == len(anum) and \
					tryresult > anum:
						if i < len(trynum) - 1:
							trynum[i] -= 1
							trynum[i+1] = 1
							break
						else:
							trynum[i] -= 1
							break
					else:
						trynum[i] += 1
						k +=1
			for n in trynum:
				result.append(str(n))
			return result

利用try number 逐位尝试,直到找到小于,但最接近商的整数为止(如果能整除则刚好相等了)。 先通过列表长度确定try number的位数,然后从高位开始递增并与被除数相乘, 当大于除数时回退1, 并将挨着的低位置为1, 直到最低位即得出结果了。


除法接口函数:

def huge_div(self, a, b):
		asign = self._huge_init(a)[0]
		anum = self._huge_init(a)[1]
		bsign = self._huge_init(b)[0]
		bnum = self._huge_init(b)[1]
		#rsign: 0 -> + ; 1 -> -
		if bnum[0] == 0 and len(bnum) == 1:
			return None
		else:
			rsign = asign ^ bsign
			result =''.join(self._div_operate(anum, bnum))
			if rsign:
				result = '-' + result
			return result

和乘法一样, 用符号位异或来确定符号。

测试结果:

['2000', '1000', '1000'] 		Passed!

['0', '0', '0'] 		Passed!

['1', '0', '1'] 		Passed!

['0', '1', '-1'] 		Passed!

['337618', '3495', '334123'] 		Passed!

['-219', '-98', '-121'] 		Passed!

['3', '-32', '35'] 		Passed!

['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'] 		Passed!

['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512', '1125899906842624'] 		Passed!

.['3', '6', '2'] 		Passed!

[None, '2', '0'] 		Passed!

['0', '0', '3'] 		Passed!

['1', '3', '2'] 		Passed!

['25', '300', '12'] 		Passed!

['-3', '-6', '2'] 		Passed!

['-3', '6', '-2'] 		Passed!

['3', '-6', '-2'] 		Passed!

['2', '115792089237316195423570985008687907853269984665640564039457584007913129639936', '57896044618658097711785492504343953926634992332820282019728792003956564819968'] 		Passed!

['57896044618658097711785492504343953926634992332820282019728792003956564819968', '115792089237316195423570985008687907853269984665640564039457584007913129639936', '2'] 		Passed!

.['12', '3', '4'] 		Passed!

['0', '32', '0'] 		Passed!

['-0', '-32', '0'] 		Passed!

['-54612', '123', '-444'] 		Passed!

['54612', '-123', '-444'] 		Passed!

['603822', '641', '942'] 		Passed!

['1831650372496', '2341234', '782344'] 		Passed!

['1007515750397959314', '1231231923', '818298918'] 		Passed!

['324518553658426726783156020576256', '18014398509481984', '18014398509481984'] 		Passed!

.['0', '1', '1'] 		Passed!

['1', '1', '0'] 		Passed!

['-1', '0', '1'] 		Passed!

['23', '45', '22'] 		Passed!

['13', '5', '-8'] 		Passed!

['26', '-3', '-29'] 		Passed!

['-2582249878086908587416174429825207663772263512260779234709013859305998087116852093665853482099976886055025678701140377600', '2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776', '2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376'] 		Passed!

.
----------------------------------------------------------------------
Ran 4 tests in 0.698s

OK

若不考虑call 等的损耗的话,算法上比二进制时间复杂度多一倍左右(因为要退位)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值