Нет сборки в зависимости, насколько я знаю ... что вы в принципе хотите, чтобы преобразовать входной сигнал в двоичную строку, а затем перебирать символы
т.е.:
- 15 -> 1111 = 2^3 + 2^2 + 2 + 1 + 2^0
- 12 -> 0110 = 2^2 + 2^1
, к сожалению, не создает встроенную функцию преобразования в двоичную строку, которую я могу найти. Существует возможность преобразования в шестнадцатеричную строку, если вы находитесь на SQL Server 2008 или более поздней версии.
DECLARE @i INT = 15
DECLARE @b VARBINARY(1) = CONVERT(VARBINARY(1),@i)
DECLARE @s NVARCHAR(2) = CONVERT(NVARCHAR(2), @b,2)
SELECT @i AS i, @b AS [binary], @s AS [hexString]
-- returns
-- i | binary | hexString
-- ------------------------------
-- 15 | 0x0F | 0F
Как только забота о 0 - 15 я был бы соблазн просто пойти с определенной пользователем функции, которая принимает дела заявление. Например:
CREATE FUNCTION fn_GetRadix(@i INT)
RETURNS NVARCHAR(255)
AS
BEGIN
DECLARE @Output NVARCHAR(255)
SELECT @Output =
CASE RIGHT(CONVERT(VARCHAR(2), CONVERT(VARBINARY(1), @i),2),1)
WHEN '0' THEN ''
WHEN '1' THEN '2^0'
-- etc etc
WHEN 'F' THEN '2^3 + 2^2 + 2^1 + 2^0'
ELSE 'something else' END
RETURN @Output
END
Не совсем идеальный, но может быть достаточно хорошим. Можно было бы получить функцию, которая работает в основном для более высоких входных значений. Вам нужно начать с преобразования в двоичную строку (см. SQL Server Convert integer to binary string), а затем итерации символов для создания вывода.
EDIT 1:
Вот функция для преобразования произвольного целого числа в двоичную строку:
CREATE FUNCTION fnGetBinaryString(@i INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @hexString NVARCHAR(MAX)
SELECT @hexString = CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), @i) ,2)
DECLARE @binString NVARCHAR(MAX) = ''
DECLARE @counter INT = LEN(@hexString)
DECLARE @char CHAR(1)
WHILE (@counter > 0)
BEGIN
SELECT @char = SUBSTRING(@hexString, @counter, 1)
SELECT @binString =
CASE @char
WHEN '0' THEN '0000' WHEN '1' THEN '0001'
WHEN '2' THEN '0010' WHEN '3' THEN '0011'
WHEN '4' THEN '0100' WHEN '5' THEN '0101'
WHEN '6' THEN '0110' WHEN '7' THEN '0111'
WHEN '8' THEN '1000' WHEN '9' THEN '1001'
WHEN 'A' THEN '1010' WHEN 'B' THEN '1011'
WHEN 'C' THEN '1100' WHEN 'D' THEN '1101'
WHEN 'E' THEN '1110' WHEN 'F' THEN '1111' END
+ @binString
SELECT @counter = @counter - 1
END
RETURN @binString
END
Теперь основываясь на том, что мы просто перебирать, хотя символы в двоичной строке справа налево, каждый раз, когда мы попали в один мы добавим результат 2^(индекс справа)
EDIT 2
А вот функция выше модифицирован, чтобы дать вам ваш желаемый выходной строки:
CREATE FUNCTION fnGetRadixString(@i INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @hexString NVARCHAR(MAX)
SELECT @hexString = CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), @i) ,2)
DECLARE @binString NVARCHAR(MAX) = ''
DECLARE @counter INT = LEN(@hexString)
DECLARE @char CHAR(1)
WHILE (@counter > 0)
BEGIN
SELECT @char = SUBSTRING(@hexString, @counter, 1)
SELECT @binString =
CASE @char
WHEN '0' THEN '0000' WHEN '1' THEN '0001'
WHEN '2' THEN '0010' WHEN '3' THEN '0011'
WHEN '4' THEN '0100' WHEN '5' THEN '0101'
WHEN '6' THEN '0110' WHEN '7' THEN '0111'
WHEN '8' THEN '1000' WHEN '9' THEN '1001'
WHEN 'A' THEN '1010' WHEN 'B' THEN '1011'
WHEN 'C' THEN '1100' WHEN 'D' THEN '1101'
WHEN 'E' THEN '1110' WHEN 'F' THEN '1111' END
+ @binString
SELECT @counter = @counter - 1
END
-- now we have a binary string representation of the number
-- iterate it from right to left
DECLARE @rString NVARCHAR(MAX) = ''
SET @counter = LEN(@binString)
DECLARE @Power INT = 0
WHILE (@counter > 0)
BEGIN
IF SUBSTRING(@binString, @counter, 1) = '1'
SELECT @rString = '2^' + CAST(@Power AS NVARCHAR(128)) + '+'
SELECT @Power = @Power + 1
SELECT @counter = @counter - 1
END
-- trim last +
IF LEN(@rString) > 0 SELECT @rString = LEFT(@rString, LEN(@rString) - 1)
RETURN @rString
END
Благодарность за IDEA..apart от преобразования в двоичную у меня есть другое approach.finding ближайший от 2 до значения мощности для заданное число. Например, для 12 ближайший 2 к значению мощности будет 2^3 = 8. Теперь 12-8 = 4. Теперь найдите ближайшее 2 к значению мощности для этого 4, которое равно 2^2. Это выглядит хорошо для меня, но я не могу написать рекурсивную функцию для этой идеи. Могу помочь мне – Santosh
@Santosh - см. дальнейшие изменения, которые я сделал, которые показывают, что эта идея реализована –