LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-12-2010, 04:41 AM   #1
sneakyimp
Senior Member
 
Registered: Dec 2004
Posts: 1,056

Rep: Reputation: 78
C function to reverse the byte order in a double?


I'm trying to write an extension to PHP which means coding in C. I'm really really rusty at C coding and was never very good at it.

Can anyone propose an efficient, safe, and [hopefully] future-proof way of reversing a double? Keep in mind that it should work on as many systems as possible and on 32- and 64-bit systems (and on ???-bit systems in the future?). Will the size of a 'double' ever change or will it always be 8 bytes?

I've tried this and it doesn't work...the compiler complains about "invalid operands to binary" because I'm trying bitwise shiftw on a non-integer.
Code:
    x = (x>>56) | 
        ((x<<40) & 0x00FF000000000000) |
        ((x<<24) & 0x0000FF0000000000) |
        ((x<<8)  & 0x000000FF00000000) |
        ((x>>8)  & 0x00000000FF000000) |
        ((x>>24) & 0x0000000000FF0000) |
        ((x>>40) & 0x000000000000FF00) |
        (x<<56);
Any advice would be much appreciated.
 
Old 08-12-2010, 05:16 AM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by sneakyimp View Post
... I'm trying bitwise shiftw on a non-integer. ...
There is type casting, as well as there are unions.

I.e. either case you double to long enough (unsigned) int or use a union whose one field will be your double and the other - long enough (unsigned) int.
 
Old 08-12-2010, 08:29 AM   #3
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Sergei Steshenko View Post
There is type casting, as well as there are unions.

I.e. either case you double to long enough (unsigned) int or use a union whose one field will be your double and the other - long enough (unsigned) int.
I agree. I nicked the following code for a previous project I supported; it supposedly is used to convert 64-bit values to Network-Byte-Order values, similar to using htons() or htonl() for short and long values.

Maybe the OP can use it:
Code:
#include <stdint.h>
#include <stdio.h>

uint64_t ntohll(const uint64_t value)
{
   enum { TYP_INIT, TYP_SMLE, TYP_BIGE };

   union
   {
      uint64_t ull;
      uint8_t  c[8];
   } x;

   // Test if on Big Endian system.
   static int typ = TYP_INIT;

   if (typ == TYP_INIT)
   {
      x.ull = 0x01;
      typ = (x.c[7] == 0x01) ? TYP_BIGE : TYP_SMLE;
   }

   // System is Big Endian; return value as is.
   if (typ == TYP_BIGE)
   {
      return value;
   }

   // else convert value to Big Endian
   x.ull = value;

   int8_t c = 0;
   c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
   c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
   c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
   c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;

   return x.ull;
}

uint64_t htonll(const uint64_t value)
{
   return ntohll(value);
}


int main(void)
{
   double value = 3.1456;

   // display bytes (of original value)
   unsigned char* cptr = (unsigned char*) &value;
   for (int i = 0; i < sizeof(double); ++i)
   {
      printf("%3d ", cptr[i]);
   }
   printf("\n");

   // convert value to Network-Byte-Order.
   uint64_t nbo = ntohll(*((uint64_t*) &value));

   // display bytes (of result)
   cptr = (unsigned char*) &nbo;
   for (int i = 0; i < sizeof(double); ++i)
   {
      printf("%3d ", cptr[i]);
   }
   printf("\n");

   return 0;
}
 
Old 08-12-2010, 11:24 AM   #4
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Well, entering

convert double to network order

into Yahoo yields as the very first match: http://www.dmh2000.com/cpp/dswap.shtml .
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Can I set the cups output order to always print in reverse order Thane Ubuntu 3 07-09-2018 09:49 PM
How to replace UTF-8 BOMs (Byte Order Marks) () in a File robbbert Linux - General 1 05-01-2008 03:40 AM
byte order conversion from network to host... adnap Programming 1 04-15-2007 04:36 AM
C : byte order of served http binary file. slzckboy Programming 5 06-22-2006 02:36 PM
double byte character kjsubbu Linux - General 5 02-04-2005 05:07 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:59 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration