Convert C# double to Delphi Real48

前端 未结 5 1176
不知归路
不知归路 2021-01-19 17:03

I\'ve found the following question Convert Delphi Real48 to C# double but I want to go the other way, C# to Delphi.

Does anyone know how this can be done? I\'ve trie

5条回答
  •  死守一世寂寞
    2021-01-19 17:53

    If you're familiar with C (as you're writing in C# you should be fine), check out this function. Moving it across into C# should not be too difficult.

    It's rather ugly, but neccesary I'm thinking.

    Reference: http://forums.ni.com/ni/board/message?board.id=60&message.id=3553

        enum prconverr double_to_real (double d, real *r)
        /* converts C double to Pascal real, returns error code */
    
    {
        union doublearray da;
        unsigned x;
    
        da.d = d;
    
        /* check for 0.0 */
        if ((da.a[0] == 0x0000) &&
            (da.a[1] == 0x0000) &&
            (da.a[2] == 0x0000) &&
            /* ignore sign bit */
            ((da.a[3] & 0x7FFF) == 0x0000)) {
            /* exponent and significand are both 0, so value is 0.0 */
            (*r)[2] = (*r)[1] = (*r)[0] = 0x0000;
            /* sign bit is ignored ( -0.0 -> 0.0 ) */
            return prOK;
        }
    
        /* test for maximum exponent value */
        if ((da.a[3] & 0x7FF0) == 0x7FF0) {
            /* value is either Inf or NaN */
            if ((da.a[0] == 0x0000) &&
                (da.a[1] == 0x0000) &&
                (da.a[2] == 0x0000) &&
                ((da.a[3] & 0x000F) == 0x0000)) {
                /* significand is 0, so value is Inf */
                /* value becomes signed maximum real, */
                /* and error code prInf is returned */
                (*r)[1] = (*r)[0] = 0xFFFF;
                (*r)[2] = 0x7FFF |
                          (da.a[3] & 0x8000); /* retain sign bit */
                return prInf;
            } else {
                /* significand is not 0, so value is NaN */
                /* value becomes 0.0, and prNaN code is returned */
                /* sign bit is ignored (no negative NaN) */
                (*r)[2] = (*r)[1] = (*r)[0] = 0x0000;
                /* sign bit is ignored ( -NaN -> +NaN ) */
                return prNaN;
            }
        }
    
        /* round significand if necessary */
        if ((da.a[0] & 0x1000) == 0x1000) {
            /* significand's 40th bit set, so round significand up */
            if ((da.a[0] & 0xE000) != 0xE000)
                /* room to increment 3 most significant bits */
                da.a[0] += 0x2000;
            else {
                /* carry bit to next element */
                da.a[0] = 0x0000;
                /* carry from 0th to 1st element */
                if (da.a[1] != 0xFFFF)
                    da.a[1]++;
                else {
                    da.a[1] = 0x0000;
                    /* carry from 1st to 2nd element */
                    if (da.a[2] != 0xFFFF)
                        da.a[2]++;
                    else {
                        da.a[2] = 0x0000;
                        /* carry from 2nd to 3rd element */
                        /* significand may overflow into exponent */
                        /* exponent not full, so won't overflow */
                        da.a[3]++;
                    }
                }
            }
        }
    
        /* get exponent for underflow/overflow tests */
        x = (da.a[3] & 0x7FF0) >> 4;
    
        /* test for underflow */
        if (x < 895) {
            /* value is below real range */
            (*r)[2] = (*r)[1] = (*r)[0] = 0x0000;
            if ((da.a[3] & 0x8000) == 0x8000)
                /* sign bit was set, so value was negative */
                return prNegUnderflow;
            else
                /* sign bit was not set */
                return prPosUnderflow;
        }
    
        /* test for overflow */
        if (x > 1149) {
            /* value is above real range */
            (*r)[1] = (*r)[0] = 0xFFFF;
            (*r)[2] = 0x7FFF | (da.a[3] & 0x8000); /* retain sign bit */
            return prOverflow;
        }
    
        /* value is within real range */
        (*r)[0] = (x - 894) |  /* re-bias exponent */
                  ((da.a[0] & 0xE000) >> 5) |  /* begin significand */
                  (da.a[1] << 11);
        (*r)[1] = (da.a[1] >> 5) |
                  (da.a[2] << 11);
        (*r)[2] = (da.a[2] >> 5) |
                  ((da.a[3] & 0x000F) << 11) |
                  (da.a[3] & 0x8000);  /* copy sign bit */
        return prOK;
    
    }
    

提交回复
热议问题