News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Fpu in C++

Started by thomas_remkus, December 20, 2008, 06:07:56 PM

Previous topic - Next topic

thomas_remkus

I'm trying to get some of the Fpu items working from C++. My buffer keeps returning "ERROR" or "0.0000000" and I'm not sure what it is that I'm doing wrong.

#define SRC1_REAL   2
#define SRC1_DMEM   4
#define SRC1_DIMM   8
#define SRC1_CONST  16
#define DEST_MEM    0
#define DEST_IMEM   64
#define DEST_FPU    128
#define SRC2_FPU    256
#define SRC2_REAL   512
#define SRC2_DMEM   1024
#define SRC2_DIMM   2048
#define SRC2_CONST  4096
#define STR_REG     0
#define STR_SCI     32768

#pragma comment(lib, "fpu.lib")
extern "C" DWORD __stdcall FpuFLtoA(DWORD lpSource, DWORD dwDecimalsNeeded, DWORD szBuffer, DWORD flags);

int main(int argc, char** args)
{
    double d = 1234.123456;
    DWORD perc = 10;
    char szBuffer[128];

    FpuFLtoA((DWORD)&d, perc, (DWORD)(char*)szBuffer, SRC1_REAL | SRC2_DIMM | STR_REG);

    prinf("%s\r\n", szBuffer);

    return 0;
}


RotateRight

Any chance that you trying to do this with M$ Visual C?

thomas_remkus

LOL. That's right. Does that make a difference?

RotateRight

I was looking at Raymond's doc for the function.
It mentions that the real number to string should
be an 80-bit number.  But a double is a 64-bit
number.  So I thought a "long double" would do the
trick.  It didn't.  We'll let a MS VC expert jump
in, but in the mean time try this.


#include <windows.h>
#include <stdio.h>

#define SRC1_REAL 2
#define SRC2_DIMM 2048
#define STR_REG   0

#pragma comment(lib, "fpu.lib")
extern "C" DWORD __stdcall FpuFLtoA(DWORD *lpSource, DWORD dwDecimalsNeeded, char *szBuffer, DWORD flags);

int main(int argc, char** args)
{
    long double d = 1234.123456;
    DWORD perc = 10;
    char szBuffer[128], flt[10];

    __asm {
        fld d
        fstp TBYTE PTR [flt]
    }

    FpuFLtoA((DWORD *)&flt, perc, szBuffer, SRC1_REAL | SRC2_DIMM | STR_REG);

    printf("%s\r\n", szBuffer);

    return 0;
}

thomas_remkus

That works! I tried the "long double" but that still gave off errors. Thanks for your help!!!

GregL

#5
'long double' in MSVC is 64-bit. The 80-bit extended precision floating-point data type is not supported in MSVC.

But it is in MASM! You can do all your calculations in MASM with REAL10 and then save the final result as a REAL8 (double) if you want to use it in MSVC. Use a separate MASM file and link it with the C program.

You can use fpu.lib from C if you really want to. You use void pointers for the REAL10 variables. I was just fiddling around with it once and got it to work.

Here is the fpu.h file

// Raymond Filiatreault's FpuLib
// http://www.ray.masmcode.com
//
#pragma comment(lib, "c:\\masm32\\lib\\fpu.lib")
//
int __stdcall FpuAtoFL(char* lpszSrc, void* lpDest, unsigned int UID);
int __stdcall FpuFLtoA(void* lpSrc1, int* lpSrc2, char* lpszDest, unsigned int uID);
//
int __stdcall FpuAdd(void* lpSrc1, void* lpSrc2, void* lpDest, unsigned int uID);
int __stdcall FpuSub(void* lpSrc1, void* lpSrc2, void* lpDest, unsigned int uID);
int __stdcall FpuMul(void* lpSrc1, void* lpSrc2, void* lpDest, unsigned int uID);
int __stdcall FpuDiv(void* lpSrc1, void* lpSrc2, void* lpDest, unsigned int uID);
int __stdcall FpuSqrt(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuXexpY(void* lpSrc1, void* lpSrc2, void* lpDest, unsigned int uID);
int __stdcall FpuAbs(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuTrunc(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuRound(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuChs(void* lpSrc, void* lpDest, unsigned int uID);
//
int __stdcall FpuLnx(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuLogx(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuEexpX(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuTexpX(void* lpSrc, void* lpDest, unsigned int uID);
//
int __stdcall FpuSin(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuCos(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuTan(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuArcsin(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuArccos(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuArctan(void* lpSrc, void* lpDest, unsigned int uID);
//
int __stdcall FpuSinh(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuCosh(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuTanh(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuArcsinh(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuArccosh(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuArctanh(void* lpSrc, void* lpDest, unsigned int uID);
//
int __stdcall FpuSize(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuComp(void* lpSrc, void* lpDest, unsigned int uID);
int __stdcall FpuExam(void* lpSrc, unsigned int uID);
int __stdcall FpuState(void* lpSrc, unsigned int uID);

#define SRC1_FPU 1
#define SRC1_REAL 2
#define SRC1_DMEM 4
#define SRC1_DIMM 8
#define SRC1_CONST 16

#define ANG_DEG 0
#define ANG_RAD 32

#define DEST_MEM 0
#define DEST_IMEM 64
#define DEST_FPU 128

#define SRC2_FPU 256
#define SRC2_REAL 512
#define SRC2_DMEM 1024
#define SRC2_DIMM 2048
#define SRC2_CONST 4096

#define STR_REG 0
#define STR_SCI 32768

#define FPU_PI 1
#define FPU_NAPIER 2

#define XAM_VALID 1
#define XAM_ZERO 2
#define XAM_NEG 4
#define XAM_SMALL 8
#define XAM_INFINIT 16

#define CMP_EQU 1
#define CMP_GREATER 2
#define CMP_LOWER 4


and here is the example code real10.c for MSVC 6.0

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "fpu.h"

int print_real10(void* pExt, int precision);
void waitkey(void);

int main(void)
{

    int x;
    void* pExt;
    unsigned char* pCh;

    // allocate room for the REAL10 variable
    pExt = malloc(10);

    // save Pi to the REAL10 variable
    _asm
    {
        finit
        fldpi
        mov eax, pExt
        fstp TBYTE PTR [eax]
    }

    pCh = pExt;

    // print out the bytes
    printf("Pi (REAL10) = ");
    for( x = 9 ; x >= 0 ; x-- )
    {
        printf("%02hhX ", *(pCh + x));
    }
    printf("\n");

    // print using FpuFLtoA
    printf("Pi (REAL10) = ");
    print_real10(pExt, 16);
    printf("\n");

    free(pExt);

    waitkey();
    return 0;
}

int print_real10(void* pReal10, int precision)
{
    int rv;
    char szBuff[64];

    RtlZeroMemory(szBuff, sizeof(szBuff));
    rv = FpuFLtoA(pReal10, (int*) precision, szBuff, SRC1_REAL | SRC2_DIMM | STR_REG);
    printf("%s", szBuff);
    return rv;
}

void waitkey(void)
{
    int ch;

    printf( "\nPress any key to continue...");
    ch = _getch();
    if(ch == 0 || ch == 0xE0)
    {
        _getch();
    }
    printf("\n");
}