Double to two longs (low and high) in c++

September 5, 2010 at 16:00:12
Specs: Windows XP, 2 GB
Hi everyone, I am trying to convert a double in 16-bit mode to a series of two longs as such:
double d;
long l_high, l_low;
l_low = d & 0xFFFFFFFF;
l_high = d << 32;
using Borland C++ compiler, which says "Illegal use of floating point" when I assign the values.

Any help would be appreciated.


See More: Double to two longs (low and high) in c++

Report •


#1
September 5, 2010 at 20:33:57
Illegal use of floating point
Probably because you're not allowed to perform bit operations on doubles.

I'm not sure how ol' Borland handles its memory, but you might get away with a union. Consider the following code (built as a 32-bit app on VC++), and reflect on your options. It should show you how Borland lays out its unions.

#include <iostream>
int main(int argc, char* argv[]) {
  union {
    double d;
    unsigned l[2];
  } u;
  std::cout << std::hex
    << &u.d << " ----------------------- " << (&u.d + 1) << '\n'
    << &u.l[0] << " - " << (&u.l[0] + 1) << "   " 
    << &u.l[1] << " - " << (&u.l[1] + 1) << '\n';
  return 0; 
}

Failing that, you might get away with casting the double to another type before performing your bit ops.


Report •

#2
September 6, 2010 at 15:55:37
Hi, Razor2.3.
I have tried your code, it compiles fine, however when I put values into the double, the longs are both zero, but when I put values into the longs (45), the double became 2.2233e-322.
You said "Failing that, you might get away with casting the double to another type before performing your bit ops."
What type?
Thanks.
PS: Thanks for responding so quickly.

Report •

#3
September 6, 2010 at 16:32:29
when I put values into the double, the longs are both zero
Are you sure they're longs? Not, unsigned int? Because that's what I used, since I was building a 32-bit application (and not 16-bit).

Also, to convert it to a different type, you'd need to pick a data type large enough for a double, which is always 64-bits. I'd probably use an array of ints and/or longs.

EDIT: Like so:

#include <iostream>
int main(int argc, char* argv[]) {
  double d = 2.3;
  int *l = reinterpret_cast<int*>(&d),
       i = sizeof(d) / sizeof(*l);
  std::cout << i << " l's to the double\n";
  for (int *j = l; i--; ++j)
    std::cout << *j << '\n';
  return 0; 
}


Report •

Related Solutions

#4
September 7, 2010 at 15:35:40
Hi,
I'm working in 16-bit mode so my 'signed longs' are 32 bits. Should I use unsigned longs?
Also, you said to pick a data type that is always 64 bits. In 16-bit mode, is that possible?
"I'd probably use an array of ints and/or longs"
That was what I was doing, but if I cast my double to a long (16-bit mode) before doing my bit operations, i would only get the lower 32 bits.
Thanks.

Report •

#5
September 8, 2010 at 04:28:33
Should I use unsigned longs?
As a general rule, you should use unsigned variables whenever you're dealing with numbers guaranteed not to be negative.

In 16-bit mode, is that possible?
It's possible to read to read all 64-bits as an array of some other type, yes. (See my second example.) But if you're looking for anything other than raw byte reinterpretation, a double may be the only data type capable of holding a 53 bit number; check your complier's documentation for any non-standard data type and look for something like VC++'s __int64.


Report •

#6
September 8, 2010 at 15:50:20
Hi
I tried using the __int64 data type, but the compiler says - Declaration syntax error.
This is my declaration:
unsigned __int64 qword;
I am compiling this for 16-bit mode, so does that mean that __int64 doesn't work?
I can't use a double because I can't convert it to my two longs (16 bit mode).
What can I do???

Report •

#7
September 8, 2010 at 16:05:40
I already told you: Look at your complier's documentation, see what data types it recognizes, and their respective sizes.

Report •

#8
September 9, 2010 at 15:31:03
I'm sorry, I forgot to tell you that I looked in the documentation and found the __int64 data type. 64 bits, just what I need, though when I declare it, the compiler produces errors.
Unfortunately, the documentation doesn't say much, just:
__int64 i64 __int64 big = 12345654321i64; 64 bits
unsigned __int64 ui64 unsigned __int64 hugeInt = 64 bits
1234567887654321ui64;
It doesn't say if it wouldn't work in 16-bit mode, but even when I use the example, it still complains.

Report •

#9
September 9, 2010 at 15:41:31
I don't know. I don't use Borland (or build 16-bit binaries). You might need to include some special header file. Does the documentation say anything about that?

Report •


Ask Question