2014-06-13 3 views
-2

С следующим способом мы можем поменять местами две переменных A и Bсвоп две переменные с XOR

A = A XOR B 
B = A XOR B 
A = A XOR B 

Я хочу реализовать такой метод в C++, которые работают со всеми типами (междунар, поплавок, полукокса, .. .), а также структуры. Поскольку мы знаем, что все типы данных, включая структуры, занимают определенное пространство памяти, например, 4 байта, 8 байтов

По-моему, этот метод для подкачки должен работать со всеми типами, исключая типы на основе указателей. Он должен менять содержимое памяти, что биты, из двух переменных

Мой вопрос
Я понятия не имею, как я могу реализовать такой метод в C++, который работает со структурами (те, не содержат каких-либо указателей). Кто-нибудь может мне помочь, пожалуйста?

+7

Вопрос в том, почему? Почему у людей возникают проблемы с объявлением простой временной переменной вместо того, чтобы тратить время и, вероятно, деньги на такие глупые оптимизации? –

+0

На 'float' даже? – harold

+0

@ThorstenDittmar вы правы, но я не хочу использовать дополнительную переменную –

ответ

2

Ваша проблема легко сводится к буферам необработанной памяти xor-swap. Что-то вроде того.

void xorswap(void *a, void *b, size_t size); 

Это может быть реализовано через xorswap с примитивных типов. Например:

void xorswap(void *a, void *b, size_t size) 
{ 
    if (a == b) 
     return; //nothing to do 

    size_t qwords = size/8; 
    size_t rest = size % 8; 

    uint64_t *a64 = (uint64_t *)a; 
    uint64_t *b64 = (uint64_t *)b; 
    for (size_t i = 0; i < qwords; ++i) 
     xorswap64(a64++, b64++); 
    uint8_t *a8 = (uint8_t*)a64; 
    uint8_t *b8 = (uint8_t*)b64; 
    for (size_t i = 0; i < rest; ++i) 
     xorswap8(a8++, b8++); 
} 

Я оставляю реализацию xorswap64() и xorswap8() в качестве упражнения для читателя.

Также обратите внимание, что для эффективности исходные буферы должны быть выровнены по 8 байт. Если это не так, в зависимости от архитектуры, код может работать субоптимально или вообще не работать (опять же, упражнение для читателя ;-).

Возможны другие оптимизации. Вы можете даже использовать Duff's device, чтобы развернуть последний цикл, но я не знаю, стоит ли это. Вам нужно будет профилировать его, чтобы точно знать.

+3

Как я уже указывал в комментариях: это даже опасно поставить такую ​​функцию. На всех структурах не гарантируется ничего удаленного. – cmaster

+0

Чтобы сделать это более общим, вы можете смешать его в 'CHAR_BIT' или, по крайней мере, использовать' sizeof (uint64_t) 'вместо' 8'. – Angew

+0

@cmaster: Да, это опасно, но так это 'memcpy()'. Я бы никогда не использовал этот код в реальной программе (я сомневаюсь, что это даст какое-то преимущество перед временным), но это хорошо, как упражнение по программированию. – rodrigo

0

Вы можете использовать Bitwise XOR"^" в C XOR два бита. См. here и here. Теперь до XOR 'a' и 'b' начинают XORing с восточного значащего бита до самого значащего бит.

Смежные вопросы