Reputation: 6570
I need a method by which to efficiently translate any float or double value to an array of bytes so that it preserves the comparison relationship to any other value.
Example: V1 and V2 are turned into arrays A1 and A2. If A1[0]<A2[0], then V1 must be smaller than V2. Same for larger. If A1[0]==A2[0] and A1[1]>A2[1] then V1 must be larger than V2. And so on. If all the bytes are the same, then the values V1 and V2 must be equal.
For a four byte integer I, an array that would satisfy the above condition would be [U>>24, (U>>16)&255, (U>>8)&255, U&255], where U is the uint positive value V-int.MinValue.
Since doubles are stored as 8 bytes, I expect something close to 8 bytes.
Do you think such a thing can be achieved? Thanks!
C# solution is preferred.
Upvotes: 0
Views: 124
Reputation: 59184
The standard representation for doubles and floats that is used by most languages, IEEE 754, is already very close to supporting this requirement.
In C#, you can use BitConverter.DoubleToInt64Bits or SingleToInt32Bits to get the underlying bits of a double or float directly as an integer.
In order to make comparisons work out right, you only have to fix up the way negative numbers are handled:
long bits = BitConverter.DoubleToInt64Bits( theDouble );
if (bits < 0L) {
bits ^= Int64.MaxValue;
}
The resulting long
s will then have the same numeric order as the corresponding double
s. This works for all values except Nan
, which isn't really comparable to anything else. The infinities, +0.0 and -0.0 work fine.
If you want +0.0 and -0.0 to have the same value, you can do this:
long bits = BitConverter.DoubleToInt64Bits( theDouble );
if (bits < 0L) {
bits = (bits^Int64.MaxValue)+1L;
}
Note that if you want to make your byte array, you'll probably want to convert to an unsigned integer. You need to flip the sign bit if you want to preserve the ordering, or just do it like this:
long bits = BitConverter.DoubleToInt64Bits( theDouble );
ulong arraybits;
if (bits >= 0L) {
arraybits = (1UL<<63) + (ulong)bits;
} else {
arraybits = (ulong)~bits;
}
Upvotes: 1