Endian преобразование в C подписано - PullRequest
1 голос
/ 16 декабря 2011

Я пытался записать целое число со знаком в файл с прямым порядком байтов.

Я использую этот код:

int32_t swap_int32( int32_t val )
{
    val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF ); 
    return (val << 16) | ((val >> 16) & 0xFFFF);
}

Он отлично работает с отрицательным значением, но янекоторые проблемы с положительным значением:

-5 дает мне:

$> hexdump OUTPUT
ff ff ff fb

Что правильно

, но 1337 дает мне:

  $> hexdump OUTPUT
     00 00 05 39

Вместоиз (ожидается) 00 00 39 05.

Есть ли возможность как-то лечить оба случая и получить правильный результат?Спасибо тебе.

Ответы [ 4 ]

3 голосов
/ 16 декабря 2011

Есть ли проблемы с использованием htonl ?

   #include <arpa/inet.h>

   uint32_t htonl(uint32_t hostlong);

Значения в байтах должны оставаться неизменными, поэтому даже если вы хотите, чтобы значение со знаком и htonl принимали без знака какПока вы читаете его обратно в подписанный тип, вы не должны терять данные.(Как отмечает mctylr, сетевой порядок имеет порядок байтов.)

#include <arpa/inet.h>
#include <stdio.h>

int main(int argc, char** argv) {
  int32_t pos = 1337;
  int32_t neg = -123;
  printf("host-endian:  %d => 0x%08x  %d => 0x%08x \n", 
         pos, pos, neg, neg);

  uint32_t big_endian_pos = htonl(pos);
  uint32_t big_endian_neg = htonl(neg);

  printf("Big-endian:   %d => 0x%08x %d => 0x%08x \n", 
         pos, big_endian_pos, neg, big_endian_neg);

}

И вывод на моем хосте с прямым порядком байтов:

[tmp]$ gcc endian.c  && ./a.out 
host-endian:  1337 => 0x00000539  -123 => 0xffffff85 
Big-endian:   1337 => 0x39050000  -123 => 0x85ffffff 
1 голос
/ 16 декабря 2011

Как минимум, вы должны привести к "unsigned" внутри вашей функции.

В качестве альтернативы, вы всегда можете использовать сетевые макросы "htons ()" (16-битный) и "htonl ()" (32-битный) для преобразования порядка байтов хоста в сеть (с прямым порядком байтов).

0 голосов
/ 16 декабря 2011

В системах * BSD и Linux вы можете использовать функции byteorder(9), включая bswap_32() при использовании небольшого хоста endian .

#include <sys/endian.h>  /* other platforms may need: sys/param.h endian.h or byteswap.h */
#include <stdint.h>

uint32_t in, out;

out = bswap_32(in);

Вкл.Системы MS Windows с прямым порядком байтов _byteswap_ulong включены в stdlib.h, хотя это не является стандартным.

В противном случае в Интернете можно легко найти различные примеры твилинга .

И StackOverflow

  • преобразование большого порядкового номера в младший в C {без использования предоставленного func} 2182002
  • Как преобразовать большой-диан и значения с прямым порядком байтов в C ++? 105252
  • Быстрое преобразование байтов от младшего к старшему в ASM 1358747 - 2 из 3 ответов не ориентированы на C #
0 голосов
/ 16 декабря 2011

Порядок байтов в сети имеет порядковый номер.

В POSOX UNIX есть htonl (), htons () и друзья, чтобы делать то, что вам нужно. Они гарантируют большой порядок в любой системе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...