Can the Byte Order of Double Be Safely Reversed

Can the byte order of Double be safely reversed?

There is a bitPattern method to get the bit pattern of a floating point value as an integer, and a Double(bitPattern:) initializer for the reverse conversion. From the documentation:

The bit pattern matches the binary interchange format defined by the IEEE 754 specification.

Therefore – assuming that the JVM uses the same IEEE 754 binary interchange format – the following would be safe:

let x = 12.34

// Double to binary interchange format (big endian):
let data = withUnsafeBytes(of: x.bitPattern.bigEndian) { Data($0) }

And for the reverse direction:

// Binary interchange format (big endian) to Double:
let y = data.withUnsafeBytes { Double(bitPattern: UInt64(bigEndian: $0.load(as: UInt64.self))) }

How can I reverse the byte order of an NSInteger or NSUInteger in objective-c

Cocoa (or to be exact the Foundation framework) has functions to swap the endianness of bytes: NSSwapInt, NSSwapShort, NSSwapLong, and NSSwapLongLong. These swap around the bytes no matter what - they make big-endian integers from small-endian integers and vice versa.

If you know which format you have there are other functions that swap it to the native endianness: NSSwapLittleIntToHost and NSSwapBigIntToHost. There are also the reverse functions which swap from the native format to little or big endian format: NSSwapHostIntToLittle and NSSwapHostIntToBig. Those are available for the other integer types and floating point types as well. What they do is they call the primitive swap functions on the values if necessary. So NSSwapLittleIntToHost doesn’t do anything while NSSwapBigIntToHost returns the result of NSSwapInt on a little endian machine.

Note that these take parameters of the compilers integer types and not the NSInteger type. So depending on wether you’re generating 32bit or 64bit code you have to use different functions if you are using NSInteger.

You also should not cast your byte array to an integer pointer and dereference that. It would be better to assemble the integer using bit shift operations. Your code will only work if NSInteger is 32 bit wide. If it is 64 bit then your number will be garbage or your program might even crash. But even if you are using an integer type that is always 32 bit wide (int32_t from the C99 <stdint.h> header for example) this might not work as expected.

Is it a must to reverse byte order when sending numbers across the network?

In general, you can't know the architecture of the remote system. If everyone uses a specific byte order - network byte order, then there is no confusion. There is some cost to all the reversing, but the cost of re-engineering ALL network devices would be far greater.

A1: Suppose that we were going to try to establish the byte order of the remote systems. We need to establish communication between systems and determine what byte order the remote system has. How do we communicate without knowing the byte order?

A2: If you know that both systems have the same architecture, then no you don't need to reverse bytes at each end. But you don't, in general, know. And if you do design a system like that, then you have made an network-architecture decision that excludes different CPU architectures in the future. Consider Apple switching from 86k to PPC to x86.

In C/C++ what's the simplest way to reverse the order of bits in a byte?

If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.

double byte swapping

It's not as easy as that. Just because an architecture is big-endian for integers doesn't mean it's big-endian for floating point numbers. I've heard of platforms that store integers big-endian and floats little-endian.
So first you should discover what the actual memory representation of double on your source platform is.

As for the swap itself, it's inefficient and way too much code. An additional 8-byte buffer won't kill you, so why not do this:

int ReadDouble(FILE* f, double* n) {
unsigned char* nbytes = reinterpret_cast<unsigned char*>(n);
unsigned char buf[sizeof(double)];
if (fread(buf, sizeof(double), 1, f) != 1) return FALSE;

for (int i = 0; i < sizeof(double); ++i) {
nbytes[i] = buf[sizeof(double)-1-i];
}
return TRUE;
}

Way less code, even if you decide to manually unroll the loop.

In C/C++ what's the simplest way to reverse the order of bits in a byte?

If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.



Related Topics



Leave a reply



Submit