简体   繁体   English

将双值从小端转换为大端

[英]Convert double value from little endian to Big endian

I am converting from little endian to big endian and back to little checking我正在从小端转换为大端并返回到小检查
is it right or wrong please help me是对是错请帮帮我

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>


double dx = 122992001003000;

//A method little to big endian

double bEndian(double d) {

    int *p0 = (int *) &d;
    int *p1 = p0 + 1;

    printf("1: %x %x\n", *p0, *p1);

    int tmp = *p1;
    *p1 = htonl(*p0);
    *p0 = htonl(tmp);

    printf("2: %x %x\n", *p0, *p1);

    return *(double *)p0;
}

//A method  big to little endian

double lEndian(double d) {
    int *p0 = (int *) &d;
    int *p1 = p0 + 1;

    printf("3: %x %x\n", *p0, *p1);

    int tmp = *p1;
    *p1 = ntohl(*p0);
    *p0 = ntohl(tmp);

    printf("4: %x %x\n", *p0, *p1);

    return *(double *)p0;
}

int main (int argc, char *argv[]) 
{       
    double d1 = bEndian(dx);

    double d2 = lEndian(d1);

    printf("5: %.0f\n", d2);

    if ((*(double*) &d2) == dx)
      printf("6: %.0lf\n", *(double*) &d2);
    else
      printf("7:%d\n", d2);

    return 0;
}

some time it give me result 122992001003129 why?有一段时间它会给我结果 122992001003129 为什么? also using ntohl or htonl have no difference ??也使用 ntohl 或 htonl 没有区别吗?? is it only for convention ie network to host and host to network是否仅适用于约定,即网络托管和主机到网络

Here is a function that will change the endianness.这是一个将改变字节序的函数。

#include <algorithm>
#include <cstdio>

template <class T>
T change_endian(T in)
{
    char* const p = reinterpret_cast<char*>(&in);
    for (size_t i = 0; i < sizeof(T) / 2; ++i)
        std::swap(p[i], p[sizeof(T) - i - 1]);
    return in;
}

int main()
{
    double d = 122992001003000;
    printf("%f\n", d);
    d = change_endian(d);
    printf("%f\n", d);
    d = change_endian(d);
    printf("%f\n", d);
}

Output:输出:

122992001003000.000000
0.000000
122992001003000.000000

Easy:简单:

#include <endian.h>
#include <stdint.h>

double  src_num = YOUR_VALUE;
int64_t tmp_num = htobe64(le64toh(*(int64_t*)&src_num));
double  dst_num = *(double*)&tmp_num;

However, there're certain quirks: https://en.wikipedia.org/wiki/Endianness#Floating_point但是,有一些怪癖: https : //en.wikipedia.org/wiki/Endianness#Floating_point

typedef union
{
    double d;
    unsigned char s[8];
} Union_t;

// reverse little to big endian or vice versa as per requirement
double reverse_endian(double in)
{
    int i, j;
    unsigned char t;
    Union_t val;

    val.d = in;
    // swap MSB with LSB etc.
    for(i=0, j=7; i < j; i++, j--)
    {
        t = val.s[i];
        val.s[i] = val.s[j];
        val.s[j] = t;
    }
    return val.d;
}

Simple reversal of four bytes should work四个字节的简单反转应该可以工作

double ReverseDouble( const double indouble )
{
   double retVal;
   char *doubleToConvert = ( char* ) & indouble;
   char *returndouble = ( char* ) & retVal;

   // swap the bytes into a temporary buffer
   returndouble[0] = doubleToConvert[3];
   returndouble[1] = doubleToConvert[2];
   returndouble[2] = doubleToConvert[1];
   returndouble[3] = doubleToConvert[0];

   return retVal;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM