128-битный Int в SQL Server 2012?

Я ищу лучший способ реализовать 128-битные целые числа без знака в SQL Server. Основное требование состоит в том, что он должен поддерживать побитовые операции со всеми 128 битами. (Возможно ли это даже теоретически на 64-битной машине? Я отвлекся.)

Я читал о некоторых реализациях, использующих C# и определяемые пользователем типы через сборку CLR, но я не мог определить, будут ли они поддерживать побитовые операции.

Кто-нибудь успешно сделал то, что мне нужно сделать? Мы будем очень признательны за любой вклад. Спасибо!!


person ambient    schedule 10.10.2014    source источник
comment
Я понимаю, что этому вопросу почти 5 лет; однако что касается теоретически возможного на 64-битной машине, то ответ - конечно. На большинстве процессоров вы можете выполнять сдвиг и/или арифметические операции с помощью переноса. Например, на 8-битном процессоре с этой функцией (даже на 6502, используемом вашим Commodore 64) любое переполнение будет переходить в бит переноса, который можно будет учитывать при операции над следующим байтом. Таким образом, выполнение 128-битных арифметических операций было возможно в 8-битной архитектуре, хотя и почти исключительно на языке ассемблера (большинство языков высокого уровня не знают о битах переноса).   -  person JackLThornton    schedule 20.06.2019


Ответы (1)


На стороне базы данных я бы использовал столбец binary[16].

Затем в коде кода clr вы можете перегрузить побитовые операторы в пользовательском типе:

public struct My128BitValue
{
    private readonly long _l1;
    private readonly long _l2;

    public My128BitValue(long l1, long l2)
    {
        _l1 = l1;
        _l2 = l2;
    }

    public static My128BitValue operator &(My128BitValue left, My128BitValue right)
    {
        return new My128BitValue(left._l1 & right._l1, left._l2 & right._l2);
    }

    public static My128BitValue operator |(My128BitValue left, My128BitValue right)
    {
        return new My128BitValue(left._l1 | right._l1, left._l2 | right._l2);
    }

    public static My128BitValue operator ^(My128BitValue left, My128BitValue right)
    {
        return new My128BitValue(left._l1 ^ right._l1, left._l2 ^ right._l2);
    }
}

Базовый пример CLR здесь, вам нужно выполнить методы FromByteArray и ToByteArray:

using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions
{    
    [SqlFunction()]
    public static SqlBinary bitwiseAnd128Bit(SqlBinary lhs, SqlBinary rhs)
    {
        My128BitValue v1 = My128BitValue.FromByteArray((byte[])lhs); //explicit conversion
        My128BitValue v2 = My128BitValue.FromByteArray((byte[])rhs);
        My128BitValue result = v1 & v2;
        return result.ToByteArray(); //implicit conversion
    }
}

Затем из SQL вы можете запустить bitwiseAnd128Bit для двух столбцов.

Подробнее о среде CLR читайте здесь http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.90).aspx

person weston    schedule 10.10.2014
comment
Не совсем без проблем. Один из операндов должен быть int, поэтому выполнять побитовые операции за пределами четвертого байта (или за пределами 8-го байта, если также работает bigint) нецелесообразно. - person Martin Smith; 10.10.2014
comment
Это интересный подход. Я дам ему попробовать. Можете ли вы привести пример того, как переменная My128BitValue может быть объявлена ​​и использована в SQL (после реализации CLR)? - person ambient; 10.10.2014
comment
@ambient Добавлен пример. - person weston; 10.10.2014
comment
Уэстон - только что вернулся к этому. Это решение прекрасно работает и его очень легко реализовать. Я на самом деле считаю, что это чрезвычайно элегантное и креативное решение. Спасибо! - person ambient; 22.04.2015