2

I'm looking for code that will take a 64-bit double in visual studio and convert it to a 80-bit extended (IEEE-754) double. The result should be stored in a 10 byte array (in little endian format I imagine). The reason is that I need to send the 80-bit double to a program which was written in Borland c++ and asks for this double. But I don't know how to do this since what I tried (basically taking the mantissa and exponent which are 52 and 11 bits respectively, converting the exponent so that it's 16383 offset in 15 bits and padding the mantissa to 64 bits) didn't seem to work. It is the inverse of this question.

inline void ConvertDblToLongDbl(double dbl, unsigned char aCh[10])
{
__int64 ull= *(__int64*)(&dbl);
    *(unsigned short*)&aCh[8]= (unsigned short)((ull>>52&0x7FF+15360)|  //     exponent, from 11 bits to 15 bits
        ((ull&(__int64)1<<63)?0x8000:0));   // sign, the 16th bit
    ull= ull&0xFFFFFFFFFFFFF;
    *(__int64*)&aCh[0]= ull|0x8000000000000000;
}

Thanks,
M

Community
  • 1
  • 1
Matt
  • 1,327
  • 1
  • 12
  • 21
  • 2
    One subtle difference between 64-bit FP and 80-bit FP is that is that 80-bit FP doesn't omit the leading 1 for normalized numbers. That could be what is breaking your current attempt. – Mysticial Apr 26 '12 at 05:21
  • I actually tried to compensate for that but wasn't sure how. Do I simply set the highest mantissa bit to 1? See edit for the function I tried. – Matt Apr 26 '12 at 05:35
  • Yeah. If the 64-bit `double` is not a denormal, then append a 1 to the front of the mantissa. – Mysticial Apr 26 '12 at 05:36
  • It's not denormal because it's a pretty large number (current unix time). The problem is that I cannot verify if I got it right because I don't have anything to compare it to. – Matt Apr 26 '12 at 05:45
  • That I can't help, I'm on Windows and you can't use 80-bit FP on Windows without inline assembly. – Mysticial Apr 26 '12 at 05:48
  • ...maybe you can write a small program in Borland C++ that gets the number as a string and returns the corresponding bytes? – MiMo Apr 26 '12 at 07:02
  • I was trying to download Borland c++ but couldn't because the website seemed only to have free trials and ads. I couldn't find any link to a free version. – Matt Apr 26 '12 at 18:05

2 Answers2

3

Inline assembly would be the simplest and fastest way. Like this:

void ConvertDoubleToLongDouble(double value, unsigned char result[10]) {
    __asm {
        fld value;
        mov ebx, result;
        fstp tbyte ptr [ebx];
    }
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 3
    Since it's so simple, it makes me wonder why visual studio doesn't have a 80-bit double. – Matt Apr 26 '12 at 18:03
0
ul>>52&0x7FFF+15360

The bitwise & has a lower operator precedence than addition which is given you an unexpected result.

ull= ull&0xFFFFFFFFFFFFF;

You are forgetting to shift this left 11 times.

Ian Brumby
  • 11
  • 1