News:

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

inputting real10 floats

Started by allynm, July 31, 2009, 11:12:03 PM

Previous topic - Next topic

allynm

Hello everyone -

I'm trying to do some simple FPU stuff, in this case doing a exp(x) function.  The built in FPU macro that does this expects to get a real10 number (tbyte).  When I use crt_scanf with the %Lf format, I seem to be getting doubles (real8), not real10.  I'm certainly willing to junk scanf and I have looked for something else, like a macro that will do a real8 (which scanf gobbles up nicely) to real10 conversion, or to read the data in directly as real10 data, but can't find anything.  Would some version of ReadFile accomplish this? 

Thanks,
Mark Allyn

raymond

QuoteThe built in FPU macro

Are you refering to an Fpulib function? If so, there is a very easy workaround:

fld  real8_variable   ;obtained whichever way you want

;call required exp Fpulib function, specifying source and destination on FPU

fstp  result

When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

allynm

Hello Raymond -

I'm honored that you took the time to answer my query.

Yes, I am talking about the Fpulib function. 

Thank you for your help on this.  I am sure this will fix the immediate problem.

However, I am still interested to know how to go from real8 to real110 as this seems to me to be one of those gaps that someone knows how to fill that sit there plaguing the novice like me.

Warm regards indeed,
Mark Allyn


dedndave

the fpu normally stores all floating point values internally as 80-bit extended reals
that way, all intermediate calculations are performed with high precision
if you load a real4 or real8 into the fpu, it gets converted to a real10 automatically
i suggest Ray's excellent tutorial - i use it as a reference all the time
http://www.ray.masmcode.com/tutorial/index.html

raymond

As dedndave mentioned, if you load a real4 or real8 into the fpu, it gets converted to the real10 format automatically. However, there is NO increase in the precision of the value. A REAL4 converted to the REAL10 format still retains the low precision of the REAL4.

You may enjoy the suggested tutorial.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ToutEnMasm


With 32 bits , the FPU made an internal use of the real 10.
The fpu import and export numbers have a maximum size of 8 bytes ,that is a qword.

allynm

Hi everyone-

I did read Raymond's excellent tutorial.  And I had used the FPU a bit previously.  So, I was aware of the conversion, but when I looked at the macro as discussed in the MASM Help folder, it appeared to me to require tbyte inputs, not qwords.  Hence the confusion.  I certainly will follow up on everyone's suggestions.

But, just a small point:  how does one read or write a tbyte variable? 

If you still have some time for this thread, I would appreciate some guidance.

Thanks to all,

Mark

MichaelW

I'm not sure I understand the question, but...

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\Fpu.inc
    includelib \masm32\lib\Fpu.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      buff db 34 dup(0)
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    invoke StdIn, ADDR buff, 34
    invoke StripLF, ADDR buff
    print ADDR buff,13,10,13,10

    invoke FpuAtoFL, ADDR buff, 0, DEST_FPU
    .IF eax == 0
      print "FpuAtoFL error",13,10
    .ENDIf

    invoke FpuFLtoA, 0, 810h, ADDR buff, SRC1_FPU or SRC2_DIMM
    .IF eax == 0
      print "FpuFLtoA error",13,10
    .ENDIf

    print ADDR buff,13,10,13,10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation

allynm

Hello MichaelW.

Yes, you most certainly did understand the question!  Thanks for your help.  I must have been blind/stupid yesterday.  I kept scanning thru the list of fpu macros and failed to find the critical one--fpuatof.  I feel really dumb.

Thanks to you and all who responded.

Mark A

raymond

QuoteThe fpu import and export numbers have a maximum size of 8 bytes ,that is a qword

I don't know what is meant by import and export numbers but the maximum size of numbers for the FPU is 80 bits, i.e. 10 bytes.

.data
   float1  REAL10  1.2345

.code
   fld  float1
   fstp float1


The above would load the full double extended precision of the float variable and store it with that same precision if the FPU Control Word is set to maximum precision.

HOWEVER, if the FPU is never initialized in the program NOR its precision control modified, Windows would have supplied it with only double precision. The above code would then have loaded the float1 as a tbyte but then round it to the lower precision. When storing it, it would also have been stored with the lower precision even though it is being stored as a tbyte.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ToutEnMasm


Seems you don't understand what mean an internal use of real10 numbers.
You can't enter a number more than 8 bytes (a qword ) in the fpu.
A real10 number in your source code is of no use for the fpu.
Here is AMD64 reference book,better explain
Quote
x87 instructions operate on data in three floating-point formats—32-bit single-precision, 64-bit
double-precision, and 80-bit double-extended-precision (sometimes called extended precision)—as
well as integer, and 80-bit packed-BCD formats.
x87 instructions carry out all computations using the 80-bit double-extended-precision format. When
an x87 instruction reads a number from memory in 80-bit double-extended-precision format, the
number can be used directly in computations, without conversion. When an x87 instruction reads a
number in a format other than double-extended-precision format, the processor first converts the
number into double-extended-precision format. The processor can convert numbers back to specific
formats, or leave them in double-extended-precision format when writing them to memory.
Most x87 operations for addition, subtraction, multiplication, and division specify two source
operands, the first of which is replaced by the result. Instructions for subtraction and division have
reverse forms which swap the ordering of operand

MichaelW

Quote from: ToutEnMasm on August 02, 2009, 05:25:18 AM
You can't enter a number more than 8 bytes (a qword ) in the fpu.
A real10 number in your source code is of no use for the fpu.

This C source, compiled with Borland TC 3.0, for which the CRT actually supports long doubles, shows otherwise:

#include <math.h>
#include <stdio.h>
int main()
{
  long double r10 = 3.141592653589793238462643L;
  double       r8 = 3.141592653589793238462643L;
  float        r4 = 3.141592653589793238462643L;
  long double rv10, rv8, rv4;
  asm {
      fld r10
      fstp rv10
      fld r8
      fstp rv8
      fld r4
      fstp rv4
  }
  printf( "\t3.141592653589793238462643L\n");
  printf( "real10\t%.19Lf\n", (long double) rv10);
  printf( "real8\t%.19Lf\n", (long double) rv8);
  printf( "real4\t%.19Lf\n", (long double) rv4);

  getch();
  return 0;
}


Note in the results that the value entered as a REAL10 is correct to 18 significant digits, where the value entered as a REAL8 is correct to only 16 significant digits, and the value entered as a REAL4 to only 6-7 significant digits:

        3.141592653589793238462643L
real10  3.1415926535897932400
real8   3.1415926535897931200
real4   3.1415927410125732400


eschew obfuscation

ToutEnMasm

With the fpu of a 64 bits processor,it is said in the doc of the 64 bits i have posted
Not with the fpu of a 32 bits processor.
don't mix the two fpu , that's raymond that have mixed the two.
To not be confused , we must say of which one we speak , a fpu for 32 bits processor or a fpu for 64 bits processor , they are not the same.

raymond

Quotea fpu for 32 bits processor or a fpu for 64 bits processor , they are not the same.

The FPU has not yet been modified/expanded for use on 64-bit processors. It's the same old FPU with very few additional features since the advent of the Pentiums.

tbyte input/output data was already a standard when first offered as an addon coprocessor with the 386 some 20 years ago.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

dsouza123

The x87 FPU, which supports 80 bit / 10 byte double extended precision,
instruction set has remained virtually unchanged
from the Pentium I through the latest dual 64/32 bit CPUs.  
What has changed dramatically are other instruction sets
that support lower precision floating point formats,
3DNow! (mostly on AMD), SSE, SSE2, SSE3 etc.  
The largest floating point format they support are 64 bit, 8 byte double precision.

A different issue is x87 FPU support in 32 and 64 bit Win OSes.
In 64 bit the x87 FPU isn't supported for kernel mode operations.

There is still the issue of initializing the x87 FPU to use 80 bit double extended precision
versus 64 bit double precision or 32 bit single precision.

When I have stated x87 FPU, I mean the x87 FPU instruction set available from the Pentium on.
The 8087 FPU through the x87 on 386/486 class computers don't have / fully support
some instructions available from the Pentium and further CPU generations.