在论坛看到 牛人们的 思路 特此收藏啊 以备学习
----------本机测试 1秒---------
用decimal(38,0),0秒:
SET NOCOUNT ON
GO
IF OBJECT_ID('BASED') IS NOT NULL DROP TABLE BASED
IF OBJECT_ID('TB') IS NOT NULL DROP TABLE TB
GO
CREATE TABLE BASED(ID INT PRIMARY KEY,VAL BIGINT)
INSERT INTO BASED SELECT 0,1 union all
SELECT id,power(convert(decimal(38,0),2),id) FROM(
select number as id from master..spt_values where type='p' and number>0 and number<57
)T
insert into BASED select number+57,power(convert(decimal(38,0),2),56)*power(2,number+1) from master..spt_values where type='p' and number<4
--以上求出2^1~2^60,因power函数在2^56以上时有舍去位,故分两步处理,以乘法代之
DECLARE @I INT ,@COUNT INT,@RESULT VARCHAR(MAX),@P60 decimal(38,0),@Pleft decimal(38,0)
SELECT @I=1,@RESULT='',@COUNT=10000 --@COUNT=10000就是计算2的10000次方
select @P60=val from BASED where id=60
select @Pleft=val from BASED where id=@count % 60
CREATE TABLE TB(ID INT PRIMARY KEY,VAL decimal(38,0))
INSERT INTO TB SELECT 1,1
INSERT INTO TB
SELECT number,0 FROM(
select number from master..spt_values where type='p' and number>1 and number<=@count/60+2
)T
--设总行数为 @count/60+2
WHILE @I<=@COUNT/60
BEGIN
UPDATE T1 SET T1.VAL= (T1.VAL*@P60+floor((isnull(T2.VAL,0)*@P60+floor(isnull(t3.val,0)*@P60/10000000000000000000))/10000000000000000000))%10000000000000000000
FROM TB T1 LEFT JOIN TB T2 ON T1.ID=T2.ID+1 left join tb t3 on t2.id=t3.id+1
SET @I=@I+1
END
-- @count/60 次 @P60 相乘
UPDATE T1 SET T1.VAL= (T1.VAL*@Pleft+floor((isnull(T2.VAL,0)*@Pleft+floor(isnull(t3.val,0)*@Pleft/10000000000000000000))/10000000000000000000))%10000000000000000000
FROM TB T1 LEFT JOIN TB T2 ON T1.ID=T2.ID+1 left join tb t3 on t2.id=t3.id+1
--乘以剩下的 2^(@count % 60)
SELECT @RESULT=@RESULT+right('000000000000'+CONVERT(VARCHAR(19),VAL),19) FROM TB
WHERE VAL>0
ORDER BY ID DESC
--SELECT @RESULT=CONVERT(VARCHAR(10),VAL)+@RESULT FROM TB
--WHERE and id=@count/30+2
SELECT right(@RESULT,LEN(@RESULT)-PATINDEX('%[1-9]%',@RESULT)+1)
SET NOCOUNT OFF
/*
199506311688075838488374216268358508382349683188619245
.....
*/
每次运算都*2^30,最后一次补足10000,循环数量变为原来的1/30了,而且每次的运算都是由系统进行,比进位运算要快很多,肯定是顺间出来的。
A的B次方
create FUNCTION [dbo].[powerX](@loopnumber bigint,@loopcount int)
RETURNS varchar(max)
AS
BEGIN
declare @str varchar(max)
declare @loop int
declare @len int
declare @num bigint
declare @add int
declare @output varchar(max)
set @str=cast(@loopnumber as varchar(max))
set @loop=1
while (@loop<@loopcount)
begin
set @output=''
set @add=0
set @len=len(@str)
while (@len!=0)
begin
set @num = cast(substring(@str,@len,1) as int)
set @num=@num*@loopnumber+@add
set @add=@num/10
set @output=cast(@num%10 as varchar(max)) +@output
set @len=@len-1
end
if(@add>=1)
begin
set @output = cast(@add as varchar(max))+@output
end
set @loop=@loop+1
set @str=@output
end
return @str
end
declare @val bigint
select @val=cast(dbo.powerX(2,25)as bigint)
select dbo.powerX(@val,400)
-------------------
详情 见论坛 :
http://topic.csdn.net/u/20110108/18/c4d2e6e0-ee57-4f6b-84e4-51dab792fa1f.html