Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Из двух 32bit слепить 64bit 
:(
    Опции темы
alex7851
Дата 20.8.2012, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.2.2012

Репутация: нет
Всего: нет



Задача такая. Есть два 32 битных беззнаковых целых, нужно сделать из них одно 64 битное за наименьшее число тактов, не прибегая ко всяким там сдвигам и сложениям.
На ум пришло:
Код

    unsigned int a=0x90abcdef, b=0x12345678;
    unsigned __int64 c;

    *( (unsigned int*)&c + 0 ) = b;
    *( (unsigned int*)&c + 1 ) = a;

Битхак со всеми вытекающими (gcc с желанным ключем -o3 это компилирует неверно). Мб еще как-нибудь можно? Хотя сомневаюсь.
Заранее спасибо.
PM MAIL   Вверх
casey
Дата 20.8.2012, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 20.12.2006
Где: Украина

Репутация: 1
Всего: 2



Код

union
{
    
    struct 
    {
        unsigned int a;
        unsigned int b;
    } _2uint32;
    
    unsigned __int64 c;

} my_union;

my_union._2uint32.a=0x90abcdef;
my_union._2uint32.b=0x12345678;

my_union.c; //  <-----------


хотя в принципе это то же самое

Это сообщение отредактировал(а) casey - 20.8.2012, 15:35
PM MAIL WWW   Вверх
alex7851
Дата 20.8.2012, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.2.2012

Репутация: нет
Всего: нет



Спасибо.
Цитата(casey @ 20.8.2012,  15:26)
хотя в принципе это то же самое

Ну, -o3 вдруг заработал, так что, что ваш код "законнее".
PM MAIL   Вверх
leniviy
Дата 20.8.2012, 21:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(alex7851 @  20.8.2012,  14:59 Найти цитируемый пост)
не прибегая ко всяким там сдвигам и сложениям.

Это единственный законный способ. А ваш вариант с кастованием в указатель будет работать не на всех архитектурах
Порядок байтов

Это сообщение отредактировал(а) leniviy - 20.8.2012, 21:13
PM MAIL   Вверх
Randajad
Дата 20.8.2012, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Это называется strict aliasing, поэтому ваш код не работает. smile

To casey:
Не то же самое, это полностью валидный код. smile

А чем сдвиги не устраивают? С 99% вероятностью они будут оптимизированы и выкинуты из кода.

P.S.
Код

union
{
    
    struct 
    {
        unsigned int a;
        unsigned int b;
    };
    
    unsigned __int64 c;
} my_union;

my_union.a = ...;
my_union.b = ...;


Код

union
{
    
     unsigned int arr[2];
    
    unsigned __int64 c;
} my_union;

my_union.arr[0] = ...;
my_union.arr[1] = ...;


Код

unsigned __int64 i = ...;
i |= (__int64)... << 32;


Это сообщение отредактировал(а) Randajad - 20.8.2012, 21:23
PM MAIL   Вверх
leniviy
Дата 20.8.2012, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



предлагаю протестировать производительность 

Это сообщение отредактировал(а) leniviy - 20.8.2012, 22:34

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  combine.zip 5,43 Kb
PM MAIL   Вверх
bsa
Дата 26.8.2012, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Randajad @  20.8.2012,  22:17 Найти цитируемый пост)
С 99% вероятностью они будут оптимизированы и выкинуты из кода.

к сожалению, gcc с 99% вероятностью это не делает.
PM   Вверх
Randajad
Дата 28.8.2012, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Какая разрядность? 32? Там нет регистров в 64 бита, так что юзать сдвиги он не сможет. А на x64 сдвиги быстрее доступа к памяти.
PM MAIL   Вверх
leniviy
Дата 28.8.2012, 20:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(Randajad @  28.8.2012,  19:59 Найти цитируемый пост)
так что юзать сдвиги он не сможет

Но оператор << все равно скомпилируется в рабочий код
PM MAIL   Вверх
bsa
Дата 28.8.2012, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Randajad @  28.8.2012,  20:59 Найти цитируемый пост)
Какая разрядность? 32? Там нет регистров в 64 бита, так что юзать сдвиги он не сможет. А на x64 сдвиги быстрее доступа к памяти.

причем тут разрядность? Ну не сможет компилятор сдвинуть одной операцией - сдвинет несколькими (псевдокод): r0 = r2 << n; r1 = r2 >> (32 - n);
PM   Вверх
Randajad
Дата 30.8.2012, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Какой operator<< для инта? В асмокоде получится shl.
На x86 32bit сдвиг на >= 32 невозможен в принципе. 
PM MAIL   Вверх
math64
Дата 30.8.2012, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



А чего спорить? Проверьте на примере:
Код

long long q;
long m = 1, n = 2;
int main() {
q = ((long long)m << 32) + n;
}

Код

    .comm    q,8,8
.globl m
    .data
    .align 4
    .type    m, @object
    .size    m, 4
m:
    .long    1
.globl n
    .align 4
    .type    n, @object
    .size    n, 4
n:
    .long    2
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ebx
    movl    m, %eax
    movl    %eax, %edx
    sarl    $31, %edx
    movl    %eax, %ecx
    movl    %edx, %ebx
    movl    %ecx, %ebx
    movl    $0, %ecx
    movl    n, %eax
    movl    %eax, %edx
    sarl    $31, %edx
    addl    %ecx, %eax
    adcl    %ebx, %edx
    movl    %eax, q
    movl    %edx, q+4
    popl    %ebx
    popl    %ebp
    ret
    .size    main, .-main

Сдвиги на 31 бит используются для расширения знака.
Нужно было объявить unsigned. Тогда сдвигов не будет,  хотя будет ненужное сложение:
Код

unsigned long long q;
unsigned long m = 1, n = 2;
int main() {
q = ((unsigned long long)m << 32) + n;
}

Код

    .comm    q,8,8
.globl m
    .data
    .align 4
    .type    m, @object
    .size    m, 4
m:
    .long    1
.globl n
    .align 4
    .type    n, @object
    .size    n, 4
n:
    .long    2
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ebx
    movl    m, %eax
    movl    $0, %edx
    movl    %eax, %ecx
    movl    %edx, %ebx
    movl    %ecx, %ebx
    movl    $0, %ecx
    movl    n, %eax
    movl    $0, %edx
    addl    %ecx, %eax
    adcl    %ebx, %edx
    movl    %eax, q
    movl    %edx, q+4
    popl    %ebx
    popl    %ebp
    ret
    .size    main, .-main


Это сообщение отредактировал(а) math64 - 30.8.2012, 14:51
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1149 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.