News:

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

Macro - Floating point

Started by RedXVII, March 29, 2006, 02:29:04 PM

Previous topic - Next topic

RedXVII

Anyone made a macro for returning Floating points in hex?

eg.

invoke function, 0, 0, FP(~), 0

of the form:

FP(150.34)
FP(150,34)    :wink

If not, i think ill try and write one  :bg

Red

Mark Jones

Well, part of the problem is, how are you supposed to represent a float as hex? Two 32-bit numbers, one being the Integer and one being the Fraction, are still not big enough to represent the range of a 80-bit float. Maybe that is good enough for your application, but each application is different. :bg

One method commonly used to represent floats in hex is the "exponent-mantissa" format. Google or Wikipedia ("Floating Point Arithmetic") give the details on how this works. Here's a cool tool: http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html

Suffice it to say there's a sign bit, some exponent bits, and a bunch of mantissa bits. The exponent bits "increment the sum by powers of ten" (or some other radix) and the mantissa bits provide all the other detail. Note that this format is slightly lossy - 32-bit floating-point representation is good to about a thousandth between +1E8 and -1E8, with the extremities being increasingly lossy. This can cause significant error over multiple computations, hence the use of 80-bit representation in the 8087 FPU and 128-bit in software.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

RedXVII

This is what i mean;

Bascially returns REAL4 value of 150.34. Masm cant do this, cause its lame

invoke myfucntion, 0, 0, 150.34, 0

nor can it do anything like

invoke myfucntion, 0, 0, REAL4 150.34, 0

Hence the macro ^^

Ratch

RedXVII,
     So you want to generate floating point constants, eh?  So do I.  I never tried to write a MACRO function to do this.  Does anyone know if Pelle's Macro Processor is able to perform this task?  If so, why bother to write a floating point constant MACRO function?  Besides, I am not too sure there is enough functionally in the MACRO language to accomplish the feat.  Ratch

MazeGen

Petroizki uses @IsFloat macro for this purpose. It can be found in his "pmacros":

http://www.masmforum.com/simple/index.php?topic=1063.0

Check the documentation - he replaced INVOKE with FNCALL macro. This FNCALL macro accepts also float constants. It is obvious from the source code how it works.

Ratch

MazeGen,
     @IsFloat only checks whether the number begins with a minus sign or digit, and contains a period.  By the way, it should also check whether the number begins with a plus sign.  That is not generating a floating point constant.  "FNCALL" might very well accept a floating point constant as a parameter, but when it passes the parameter to a instruction like MOV EAX,FP_PARAM within the MACRO, is a floating point constant generated?  I think not.  Ratch

MazeGen

Ratch,

if I got RedXVII right, all what he needs is to pass REAL4 parameter directly to some function. I directed him to FNCALL because it shows how it can be done. RedXVII could use it as an example how to make its own macros.

u

With "invoke", the only reasonable way I found now is by using eax:

FP macro what
db 0B8h ; mov eax,imm32
real4 what
exitm <eax>
endm


lqlq proc Float1

fld Float1
fistp Float1
mov eax,Float1
ret
lqlq endp



main proc
invoke lqlq,FP(1.2)

ret
main endp



Using "org" and other tricks can't work here, so eax prolly is the only way ^^", except for the obvious:

FP2 macro what
local fdat1
.data
fdat1 real4 what
.code
exitm <fdat1>
endm
Please use a smaller graphic in your signature.

raymond

Your other option for REAL4 is to declare it as data within your code. Ex.:

   .....
   jmp  @F
   f4150p34  dd  150.34
@@:
   invoke  function, 0, 0, f4150p34, 0


If you need REAL8 or REAL10, your function must then expect the address of the float. You could then do it as follows:

   .....
   jmp  @F
   f8150p34  dq  150.34
@@:
   invoke  function, 0, 0, ADDR f8150p34, 0


The above may not be considered the "cleanest" way because there is a risk that the variables may not be aligned on a dword boundary (as compared to declaring it in the .data section where you have easy control on the boundary).

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

u

Just a correction to Raymond's post - with "invoke" you can use real8/qword and real10 as parameters!


lqlq proc z:real8
PrintDouble z
ret
lqlq endp

d1 real8 1.5

main proc

invoke lqlq,d1

"invoke" is intelligent enough to push the data correctly on stack :)

Also, FP() for doubles:

FP2 macro Double
local myDbl
.data
myDbl real8 Double
.code
exitm <myDbl>
endm
Please use a smaller graphic in your signature.