Использование этот ответ хорош, потому что он очень переносим, корректен и проходит строгие компиляторы, но он менее эффективен, чем я хочу, и мог бы быть, потому что он не использует x86 инструкция bswap. (Возможно, другие наборы инструкций имеют аналогичные эффективные инструкции.)
Если система, на которой я работаю, поддерживает ntohl()
, тогда я ожидаю, что ntohl()
использует инструкцию bswap и приблизит меня. ntohl()
делает все правильно, но работает только с uint32_t, а не с плавающей точкой. Преобразование между uint32_t и float является типом пробивки и не допускается строгими компиляторами. Создание объединения с плавающей точкой и uint32_t приводит к неопределенному поведению компилятора (за предыдущие посты здесь).
Насколько я понимаю из предыдущих постов, приведение из любого типа указателя к символу * или наоборот явно разрешено. Так что же не так с этим решением? Я еще ни разу не упоминал об этом.
char NetworkOrderFloat[4]; // Assume it contains network-order float bytes
uint32_t HostOrderInt = ntohl(*(uint32_t *)NetworkOrderFloat);
char *Pointer = (char *)&HostOrderInt;
float HostOrderFloat = *(float *)Pointer;
Идеальным решением здесь, по-видимому, является большее количество сред, поддерживающих ntohf (), но, похоже, этого еще не произошло.