Float numbers

  • 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?

  • This was removed by the editor as SPAM

  • 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

  • Thank you for your try. But it's not working correctly, even on the given exmaple, 101E50%221=155

  • Sorry. I only tested it on (too) small numbers. Looks like the floor function does not work with large numbers.

  • 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
    ----------------------------------------

  • 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

    SET @C = (@c * @b-2) % @m

    --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

    SET @C = (@c * @b1) % @m

    END

    SET @e1 = @e1 / 2

    SET @b1 = (@b1 * @b1) % @m

    END

    SELECT @C AS Modulus

  • This was removed by the editor as SPAM

  • 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