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
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy