December 27, 2010 at 10:47 pm
Hi. How can I get mod of very very big numbers? For example, how to find the result of select power(cast(101 as float),50)%221?
December 28, 2010 at 4:03 am
This was removed by the editor as SPAM
December 29, 2010 at 12:39 pm
You can mimick the modulo operator on floating point operands like below
with BigNumber(N, D) as
(
-- select power(cast(101 as float), 50)
select
101E50, -- E50 makes it a float constant
221
)
select
N,
floor(abs(N) / abs(D)) * D * sign(N),
N - (floor(abs(N) / abs(D)) * D * sign(N) * sign(D))
from
BigNumber
December 29, 2010 at 11:50 pm
Thank you for your try. But it's not working correctly, even on the given exmaple, 101E50%221=155
December 30, 2010 at 3:45 am
Sorry. I only tested it on (too) small numbers. Looks like the floor function does not work with large numbers.
January 4, 2011 at 8:15 am
can't you just cast your float as a bigint?
as in, if you have 15 dec places, multiply it by 10^15, cast as an int, do mod, then cast result as a float and divide by 10^15?
Or am I being stupid to an unprecedented degree?
Ben
^ Thats me!
----------------------------------------
01010111011010000110000101110100 01100001 0110001101101111011011010111000001101100011001010111010001100101 01110100011010010110110101100101 011101110110000101110011011101000110010101110010
----------------------------------------
January 4, 2011 at 12:45 pm
This isn't really something that TSQL is well suited for, since the various solutions require an iterative approach. However, if you want to find the modulus of a large integer that is defined in exponential form b to the power e (where in your example: b=101, e=50), then you can use either of the following two methods, which I've taken directly from http://en.wikipedia.org/wiki/Modular_exponentiation
DECLARE @e int
DECLARE @b-2 int
DECLARE @m int
DECLARE @e1 int
DECLARE @b1 bigint
DECLARE @C bigint
-- To find: POWER(@b, @e) % @m where POWER(@b, @e) is too large be stored in a bigint.
SELECT @b-2 = 101, @e = 50, @m = 221
--Method 1
SELECT @e1 = 0, @C = 1
WHILE (@e1 < @e) BEGIN
SET @e1 = @e1 + 1
--PRINT @C
END
SELECT @C AS Modulus
--Method 2 (requires fewer iterations and therefore should be more efficient where @e is large)
SELECT @b1 = @b-2, @e1 = @e, @C = 1
WHILE (@e1 > 0) BEGIN
IF ((@e1 & 1) = 1) BEGIN
END
SET @e1 = @e1 / 2
SET @b1 = (@b1 * @b1) % @m
END
SELECT @C AS Modulus
January 4, 2011 at 11:26 pm
This was removed by the editor as SPAM
January 5, 2011 at 6:09 am
Here's an alternative query based on method 2 of my previous post, but uses a recursive CTE instead of a WHILE loop. I haven't compared the various methods for performance.
DECLARE @e int
DECLARE @b-2 int
DECLARE @m int
-- To find: n mod m where n = POWER(b, e) is too large be stored in a bigint.
SELECT @b-2 = 101, @e = 50, @m = 221
;WITH cteRecurse AS (
SELECT
CAST(1 AS bigint) AS result,
CAST(@b AS bigint) AS base,
@e AS exponent
UNION ALL
SELECT
CASE WHEN ((exponent & 1) = 1) THEN (result * base) % @m ELSE result END,
(base * base) % @m,
exponent / 2
FROM cteRecurse
WHERE (exponent > 0)
)
SELECT result AS Modulus
FROM cteRecurse
WHERE (exponent = 0)
EDIT: Changed text in TSQL comment
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply