вы можете использовать BCP для небольших таблиц.
Команда BCP OUT: -
BCP "SELECT * FROM [Dinesh].[dbo].[Invoices]" QUERYOUT C:\av\Invoices1.txt -S MC0XENTC -T -c -r c:\error.csv
Команда BCP IN: - Создать структуру таблицы для Invoicescopy1.
BCP [Dinesh].[dbo].[Invoicescopy1] IN C:\av\Invoices.txt -S MC0XENTC -T -c
Операторы смещения бита делают точно, что подразумевает их имя. Они смещают биты. Вот является резюме (или not-so-brief) введением в различные операторы сдвига.
>>
арифметика (или подписанный) оператор сдвига вправо. >>>
логическое (или неподписанный) оператор сдвига вправо. <<
левый оператор смещения и удовлетворяет потребности и логических и арифметических сдвигов. Все эти операторы могут быть применены к целочисленным значениям (int
, long
, возможно short
и byte
или char
). На некоторых языках, применяя операторы сдвига к любому типу данных, меньшему, чем [1 119] автоматически, изменяет размеры операнда, чтобы быть int
.
Примечание, которое <<<
не является оператором, потому что это было бы избыточно.
Также примечание, что C и C++ не различают операторы сдвига вправо . Они обеспечивают только >>
оператор, и смещающее право поведение является реализацией, определенной для типов со знаком. Остальная часть ответа использует операторы C# / Java.
(Во всей господствующей тенденции C и реализациях C++ включая gcc и clang/LLVM, >>
на типах со знаком арифметика. Некоторый код принимает это, но это не что-то стандартные гарантии. Это не не определено , хотя; стандарт требует, чтобы реализации определили его так или иначе. Однако сдвиги влево отрицательных чисел со знаком неопределенное поведение (переполнение целого числа со знаком). Таким образом, если Вам не нужен арифметический сдвиг вправо, это обычно - хорошая идея сделать Ваше смещение бита с неподписанными типами.)
Целые числа хранятся, в памяти, как ряд битов. Например, номер 6, сохраненный как 32-разрядное int
, был бы:
00000000 00000000 00000000 00000110
Смещение этой комбинации двоичных разрядов налево одно положение (6 << 1
) привело бы к номеру 12:
00000000 00000000 00000000 00001100
, Как Вы видите, цифры сместились налево одним положением, и последняя цифра справа заполнена нулем. Вы могли бы также отметить, что оставленное смещение эквивалентно умножению полномочиями 2. Так 6 << 1
эквивалентно [1 127], и 6 << 3
эквивалентно [1 129]. Хороший оптимизирующий компилятор заменит умножение сдвигами, если это возможно.
Обратите внимание на то, что, это не циклические сдвиги. Смещение этого значения налево одним положением (3,758,096,384 << 1
):
11100000 00000000 00000000 00000000
результаты в 3,221,225,472:
11000000 00000000 00000000 00000000
цифра, которая смещается "от конца", потеряна. Это не повторяется.
<час>А логический сдвиг вправо является обратным к сдвигу влево. Вместо движущихся битов налево, они просто перемещаются направо. Например, смещение номера 12:
00000000 00000000 00000000 00001100
направо одним положением (12 >>> 1
) возвратит наш оригинал 6:
00000000 00000000 00000000 00000110
, Таким образом, мы видим, что смещение направо эквивалентно подразделению полномочиями 2.
Однако, сдвиг не может исправить "потерянные" биты. Например, если мы смещаем этот шаблон:
00111000 00000000 00000000 00000110
левым 4 положения (939,524,102 << 4
), мы добираемся 2,147,483,744:
10000000 00000000 00000000 01100000
и затем смещающийся назад ((939,524,102 << 4) >>> 4
) мы добираемся 134,217,734:
00001000 00000000 00000000 00000110
Мы не можем возвратить наше исходное значение, как только мы потеряли биты.
<час>арифметический сдвиг вправо точно похож на логический сдвиг вправо, кроме вместо того, чтобы дополнить нулем, это дополняет старшим значащим битом. Это вызвано тем, что старший значащий бит , знак укусил, или бит, который отличает положительные и отрицательные числа. Путем дополнения старшим значащим битом арифметический сдвиг вправо является сохранением знака.
, Например, если мы интерпретируем эту комбинацию двоичных разрядов как отрицательное число:
10000000 00000000 00000000 01100000
у нас есть номер-2 147 483 552. Смещение этого к правильным 4 позициям с арифметическим сдвигом (-2 147 483 552>> 4) дал бы нам:
11111000 00000000 00000000 00000110
или номер-134 217 722.
, Таким образом, мы видим, что сохранили знак наших отрицательных чисел при помощи арифметического сдвига вправо, а не логического сдвига вправо. И еще раз, мы видим, что выполняем подразделение полномочиями 2.
Один глюк - то, что следующее является зависящим от реализации (согласно стандарту ANSI):
char x = -1;
x >> 1;
x может теперь быть 127 (01111111) или все еще-1 (11111111).
На практике, это обычно - последний.
Битовые операции, включая сдвиг разряда, фундаментальны для аппаратных средств низкого уровня или встроенного программирования. При чтении спецификации для устройства или даже некоторых форматов двоичного файла Вы будете видеть байты, слова, и dwords, разбитый в небайт, выровнял битовые поля, которые содержат различные значения интереса. Доступ к этим битовым полям для чтения/записи является наиболее распространенным использованием.
А простой реальный пример в графическом программировании - то, что 16-разрядный пиксель представлен следующим образом:
bit | 15| 14| 13| 12| 11| 10| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Blue | Green | Red |
Для достигания зеленого значения Вы сделали бы это:
#define GREEN_MASK 0x7E0
#define GREEN_OFFSET 5
// Read green
uint16_t green = (pixel & GREEN_MASK) >> GREEN_OFFSET;
Объяснение
для получения значения зеленого цвета ТОЛЬКО, который запускается при смещении 5 и заканчивается в 10 (т.е. 6 битов длиной), необходимо использовать (разрядную) маску, которая, когда применено против всего 16-разрядного пикселя, приведет только к битам, которыми мы интересуемся.
#define GREEN_MASK 0x7E0
соответствующая маска является 0x7E0, который в двоичном файле равняется 0000011111100000 (который является 2016 в десятичном числе).
uint16_t green = (pixel & GREEN_MASK) ...;
Для применения маски Вы используете операцию И (&).
uint16_t green = (pixel & GREEN_MASK) >> GREEN_OFFSET;
После применения маски, Вы закончите с 16-разрядным числом, которое является действительно просто 11-разрядным числом, так как его MSB находится в 11-м бите. Зеленый на самом деле только 6 битов длиной, таким образом, мы должны масштабировать его вниз использование сдвига вправо (11 - 6 = 5), следовательно использование 5, как смещено (#define GREEN_OFFSET 5
).
Также распространенный использует сдвиги разряда для быстрого умножения и разделения полномочиями 2:
i <<= x; // i *= 2^x;
i >>= y; // i /= 2^y;
Скажем, у нас есть единственный байт:
0110110
Применение единственного левого сдвига разряда получает нас:
1101100
крайний левый нуль был смещен из байта, и новый нуль был добавлен к правильному концу байта.
биты не делают трансформации; они отбрасываются. Это означает, не вернете ли Вы сдвиг влево 1101100 и затем сдвиг вправо это, Вы тот же результат.
Смещение, оставленное N, эквивалентно умножению на 2 <глоток> N глоток>.
Смещающееся право N (если Вы используете дополнение ), эквивалент деления на 2 <глоток> N глоток> и округление для обнуления.
Bitshifting может использоваться для безумно быстрого умножения и разделения, если Вы работаете с питанием 2. Почти все стандартные программы низкокачественной графики используют bitshifting.
, Например, путь назад в былые дни, мы использовали 13-й режим (320x200 256 цветов) для игр. В 13-м Режиме видеопамять была размечена последовательно на пиксель. Это означало вычислять местоположение для пикселя, Вы будете использовать следующую математику:
memoryOffset = (row * 320) + column
Теперь, назад в тот день и возраст, скорость была очень важна, таким образом, мы будем использовать сдвиги разряда, чтобы сделать эту операцию.
Однако 320 не питание два, так для обхождения этого мы должны узнать то, что является питанием два, который добавил, вместе делает 320:
(row * 320) = (row * 256) + (row * 64)
Теперь мы можем преобразовать это в сдвиги влево:
(row * 320) = (row << 8) + (row << 6)
Для конечного результата:
memoryOffset = ((row << 8) + (row << 6)) + column
Теперь мы получаем то же смещение как прежде, кроме вместо дорогой операции умножения, мы используем эти два сдвига разряда... в x86, это было бы что-то вроде этого (примечание, это было навсегда, так как я сделал блок (примечание редактора: исправленная пара ошибок и добавила 32-разрядный пример)):
mov ax, 320; 2 cycles
mul word [row]; 22 CPU Cycles
mov di,ax; 2 cycles
add di, [column]; 2 cycles
; di = [row]*320 + [column]
; 16-bit addressing mode limitations:
; [di] is a valid addressing mode, but [ax] isn't, otherwise we could skip the last mov
Общее количество: 28 циклов на любом древнем ЦП имели эти синхронизации.
циклы Vrs
mov ax, [row]; 2 cycles
mov di, ax; 2
shl ax, 6; 2
shl di, 8; 2
add di, ax; 2 (320 = 256+64)
add di, [column]; 2
; di = [row]*(256+64) + [column]
12 на том же древнем ЦП.
Да, мы работали бы это трудно для бритья 16 циклов ЦП.
В 32 или 64-разрядный режим, обе версии становятся намного короче и быстрее. Современные центральные процессоры выполнения с изменением последовательности как Intel Skylake (см. http://agner.org/optimize/ ) имеют очень быстрые аппаратные средства, умножаются (низкая задержка и высокая пропускная способность), таким образом, усиление намного меньше. Семья бульдозера AMD немного медленнее, специально для 64-разрядного умножаются. На Intel CPUs и AMD Ryzen, два сдвига являются немного более низкой задержкой, но больше инструкций, чем умножение (который может вести для понижения пропускной способности):
imul edi, [row], 320 ; 3 cycle latency from [row] being ready
add edi, [column] ; 1 cycle latency (from [column] and edi being ready).
; edi = [row]*(256+64) + [column], in 4 cycles from [row] being ready.
по сравнению с [1 137]
mov edi, [row]
shl edi, 6 ; row*64. 1 cycle latency
lea edi, [edi + edi*4] ; row*(64 + 64*4). 1 cycle latency
add edi, [column] ; 1 cycle latency from edi and [column] both being ready
; edi = [row]*(256+64) + [column], in 3 cycles from [row] being ready.
Компиляторы сделают это для Вас: Посмотрите как gcc, лязг и MSVC все использование shift+lea при оптимизации return 320*row + col;
.
самая интересная вещь отметить вот состоит в том, что x86 имеет инструкцию shift-and-add (LEA
) , который может сделать маленькие сдвиги влево и добавить одновременно с представлением в качестве и add
инструкция. ARM еще более мощен: один операнд любой инструкции может быть лев или прав смещенный бесплатно. Так масштабируясь постоянным во времени компиляцией это, как известно, является power-2, может быть еще более эффективным, чем умножение.
хорошо, назад в современные дни... что-то более полезное теперь должно было бы использовать bitshifting для хранения двух 8-разрядных значений в 16-разрядном целом числе. Например, в C#:
// Byte1: 11110000
// Byte2: 00001111
Int16 value = ((byte)(Byte1 >> 8) | Byte2));
// value = 000011111110000;
В C++, компиляторы должны сделать это для Вас, если бы Вы использовали struct
с двумя 8-разрядными участниками, но на практике сделайте не всегда.