News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Converting real8 to string

Started by RuiLoureiro, April 30, 2013, 04:07:27 AM

Previous topic - Next topic

qWord

Quote from: jj2007 on May 02, 2013, 04:31:51 AMSo the question is, why do Windows (and CRT, it seems) unnecessarily sacrifice precision, if full precision is not slower? To maintain compatibility, in the negative sense, with SSE-based libraries? ::)
to be compatible with IEEE 754, which is required by many HLLs.(?)
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

probably the right answer
most compilers support single and double types, few offer much support for extended reals

jj2007

Quote from: dedndave on May 02, 2013, 05:25:26 AM
probably the right answer

Caution, the guy has 666 posts :greensml:

Jokes apart: SmplMath is REAL10, I suppose?

qWord

Quote from: jj2007 on May 02, 2013, 05:40:54 AMJokes apart: SmplMath is REAL10, I suppose?
for x32 programs, the FPU is used by default whereas the macros does not touch the control word thus the programmer is responsible for that (of course there are helper macros for that). However, for creation of constants REAL8 is the default**.


**RTFM for details :biggrin:
MREAL macros - when you need floating point arithmetic while assembling!

RuiLoureiro

#34
Quote from: qWord on May 02, 2013, 03:22:18 AM
simply set the precision control to 53 or 24 bit and use corresponding values and constants - loading REAL10 values is still possible, but the precision is lost after the first operation1 (due rounding to 53/24 bit).

1: +-*/sqrt()

From Simply FPU by raymond

Control Word
-----------------
The Control Word 16-bit register is used by the programmer to select
between the various modes of computation available from the FPU

The PC field (bits 9 and 8.) or Precision Control determines to what
precision the FPU rounds results after each arithmetic instruction
in one of three ways:

00 = 24 bits (REAL4)
01 = Not used
10 = 53 bits (REAL8)
11 = 64 bits (REAL10) (this is the initialized state)

FINIT / FNINIT (Initialize FPU)
------------------------------------
This instruction initializes the FPU by resetting all
the registers and flags to their default values

    conclusion: we may work in real4 mode or in real8 mode or in real10 mode
                but the FPU is initialized in real10 mode.
                So we need to use FLDCW and FSTCW or only FSTCW to set it
                to real4 or real8

dangerous advices
------------------------

    one very important rule when we do computations is this:
    we should round the result only at the end of a series
    of calculations and NEVER after each operation.

    So, it means that the modes exist but it is useless
    (at least for me).

    i dont know if it takes less time or not (it seems not)
    working in real4 or real8 mode, but i never will use it.
    It's simple, of course.
    I will not return to 16 bits era also.  ;)
    That' all

RuiLoureiro

#35
ToutEnMasm

Quote
Too much difficult ?
Here is a standard api call
No. The only thing is this: i dont like to
            use structures.
            The question seems to be this: There is a
            "standard api call" and "my standard api call" !
            and i dont want to change.
            Also, it seems you like to use "proc uses ebx esi edi"
            and i dont like, i hate it.
            So it seems that the best way is to remove the instruction
            that set the length at [edi-4]. But well you should do
            as you like.  :t

           EDIT:
            About the buffer
            --------------------

            The question is this: why we need to specify a buffer
            to convert a number to string everytime we want to
            print a number if we dont need the buffer ?

            To solve this question we may do this:

            invoke  ConvertReal8DF, addr Real8, 0           <- 0=> no buffer

            (ConvertReal8DF uses ConvertFloat8DF)

            but ConvertReal8DF should return the internal buffer
            address and the question is: whats the best register ?
            may be EDX.

EDIT:
     another important question

     If i use structure as you suggest
     i destroy the logic i follow of
     «1 address 2 things». So we need
     to get the starting address of that
     structure and we need to add 4,
     exactly what i dont want to do. We dont
     need to add nothing. If i have
     the address i have the buffer
     forward and the length behind of
     that address. This is the logic.

dedndave

in Ray's tutorial, it says that REAL10 is the precision after initialization
that is true after executing FINIT
however, windows sets it to REAL8 before handing control over to an EXE

i usually do an FINIT at the start of my FPU code   :P
i should probably just set the precision - a little more code, but faster than FINIT

RuiLoureiro

Quote from: dedndave on May 02, 2013, 10:46:48 PM
however, windows sets it to REAL8 before handing control over to an EXE
At the start up i do finit ever, so what windows do doesnt matter
              what some other procs do doesnt matter because i dont use it,
              i dont trust.

the code i posted to test the converter we have:           
.code
;====================================================
start:
            finit

              Well, Dave, how do i use crt procs to convert a real8 to string. I want
              to test it, could you help me ?

dedndave

sprintf can do it
http://msdn.microsoft.com/en-US/library/ybk95axf%28v=vs.80%29.aspx

MyReal REAL8 3.14
szFormat db '%9.7lf',0
szBuffer db 20 dup (?)

        invoke  crt_sprintf,offset szBuffer,offset szFormat,MyReal
        print   offset szBuffer
        print   chr$(13,10)

i didn't test that, but it should work   :P
i am not a big "C" guy - lol

EDIT: corrected the code so it works   :biggrin:
you can play with the format string to get different digit counts

Gunther

Hi Dave,

Quote from: dedndave on May 02, 2013, 10:46:48 PM
in Ray's tutorial, it says that REAL10 is the precision after initialization
that is true after executing FINIT
however, windows sets it to REAL8 before handing control over to an EXE

REAL10 and Windows is a very strange story. You should check that thread again.

Gunther
You have to know the facts before you can distort them.

RuiLoureiro

#40
I duplicate the ConvertFloat8 procedures
and replaced Float by Real. If i use ConvertFloat
in ConvertReal we dont get good results.

The new ConvertReal accept 0 to buffer address,
and, in that case, they use an internal buffer
and is null terminated only (it has not length)
and return the pointer in EDX.

These are the last results
. If ConvertReal, buffer address=0
. 3 last letters after 8 means we specify decimal places
. examine is CPU code while fxam is FPU instruction
. ebp means local variables, esp means use esp to get
variables from stack
. In ...8DZ and ...8DZD we use the value not the address

I got 7904 cycles, crt_sprintf, _Real8_2 but we cannot compare
because it uses format string.

Quote
***** Time table *****

324   cycles, ConvertFloat8DXD, direct, fxam, fxtract, esp - 15 digits
327   cycles, ConvertReal8DYD, direct, examine, fxtract, esp - 15 digits
327   cycles, ConvertFloat8DYD, direct, examine, fxtract, esp - 15 digits
328   cycles, ConvertReal8DXD, direct, fxam, fxtract, esp - 15 digits
333   cycles, ConvertReal8DRD, direct, examine, fxtract, ebp - 15 digits
333   cycles, ConvertFloat8DRD, direct, examine, fxtract, ebp - 15 digits
457   cycles, ConvertFloat8DFD, direct, examine, fyl2x, ebp - 15 digits
462   cycles, ConvertReal8DFD, direct, examine, fyl2x, ebp - 15 digits
467   cycles, ConvertFloat8DSD, direct, fxam, fyl2x, ebp - 15 digits
472   cycles, ConvertReal8DSD, direct, fxam, fyl2x, ebp - 15 digits
692   cycles, ConvertFloat8CTD, BCD-CT, fxam, fxtract, esp - 15 digits
699   cycles, ConvertReal8CTD, BCD-CT, fxam, fxtract, esp - 15 digits
703   cycles, ConvertReal8BF, BCD, fxam, fxtract, esp - 15 digits
703   cycles, ConvertFloat8BF, BCD, fxam, fxtract, esp - 15 digits
704   cycles, ConvertFloat8BXD, BCD, fxam, fxtract, ebp - 15 digits
704   cycles, ConvertFloat8BFD, BCD, fxam, fxtract, esp - 15 digits
705   cycles, ConvertFloat8BYD, BCD, examine, fxtract, esp - 15 digits
706   cycles, ConvertReal8BXD, BCD, fxam, fxtract, ebp - 15 digits
708   cycles, ConvertFloat8BX, BCD, fxam, fxtract, ebp - 15 digits
709   cycles, ConvertReal8BY, BCD, examine, fxtract, esp - 15 digits
710   cycles, ConvertReal8BFD, BCD, fxam, fxtract, esp - 15 digits
712   cycles, ConvertReal8CT, BCD-CT, fxam, fxtract, esp - 15 digits
713   cycles, ConvertReal8BYD, BCD, examine, fxtract, esp - 15 digits
714   cycles, ConvertFloat8BY, BCD, examine, fxtract, esp - 15 digits
722   cycles, ConvertFloat8CT, BCD-CT, fxam, fxtract, esp - 15 digits
725   cycles, ConvertReal8BX, BCD, fxam, fxtract, ebp - 15 digits
1066  cycles, ConvertFloat8Z, BCD -old - 15 digits
1075  cycles, ConvertFloat8DX, direct, fxam, fxtract, esp - 15 digits
1081  cycles, ConvertReal8DY, direct, examine, fxtract, esp - 15 digits
1083  cycles, ConvertFloat8DY, direct, examine, fxtract, esp - 15 digits
1084  cycles, ConvertReal8DX, direct, fxam, fxtract, esp - 15 digits
1087  cycles, ConvertFloat8DR, direct, examine, fxtract, ebp - 15 digits
1113  cycles, ConvertFloat8ZX, BCD - old - 15 digits
1114  cycles, ConvertReal8DR, direct, examine, fxtract, ebp - 15 digits
1153  cycles, ConvertReal8DZ, direct, fxam, fxtract, esp - 15 digits
1158  cycles, ConvertFloat8DZ, direct, fxam, fxtract, esp - 15 digits
1159  cycles, ConvertFloat8DZD, direct, fxam, fxtract, esp - 15 digits
1164  cycles, ConvertReal8DZD, direct, fxam, fxtract, esp - 15 digits
1202  cycles, ConvertFloat8DS, direct, fxam, fyl2x, ebp - 15 digits
1202  cycles, ConvertReal8DS, direct, fxam, fyl2x, ebp - 15 digits
1206  cycles, ConvertReal8DF, direct, examine, fyl2x, ebp - 15 digits
1211  cycles, ConvertFloat8DF, direct, examine, fyl2x, ebp - 15 digits
2585  cycles, ConvertFloat8DWD, direct,Save FPU, fxam, fxtract, esp -15 digits
2587  cycles, ConvertReal8DWD, direct,Save FPU, fxam, fxtract, esp -15 digits
2901  cycles, ConvertFloat8BWD, BCD, Save FPU, fxam, fxtract, ebp - 15 digits
2913  cycles, ConvertReal8BWD, BCD, Save FPU, fxam, fxtract, ebp - 15 digits
2917  cycles, ConvertFloat8, BCD, Save FPU -old - 15 digits
3081  cycles, ConvertFloat8BW, BCD, Save FPU, fxam, fxtract, ebp - 15 digits
3087  cycles, ConvertReal8BW, BCD, Save FPU, fxam, fxtract, ebp - 15 digits
3538  cycles, ConvertFloat8DW, direct,Save FPU, fxam, fxtract, esp -15 digits
3540  cycles, ConvertReal8DW, direct,Save FPU, fxam, fxtract, esp -15 digits
********** END **********

RuiLoureiro

#41
Hi
    Here we have the new (better) ASM procedures

        ConvertFloat8DR and ConvertFloat8DRD
        ConvertReal8DR and ConvertReal8DRD

    and the last

        ConvertFloat8DS and ConvertFloat8DSD
        ConvertReal8DS  and ConvertReal8DSD

    . Float version use length behind the address
    . Real     "    doesnt use length

    . Real version only: we may specify string address = 0
      The proc returns the address in EDX

        invoke  ConvertReal8DRD, addr _qword, 0, 14
        print   edx, 13,10

    To use it

        include     PowerTable.inc
        include     Convert8DR.inc
        include     Convert8DRD.inc
        include     Convert8DS.inc
        include     Convert8DSD.inc
       
        uncomment ;$DECIMALPLACES_REAL8  equ 15
       
   
    Test yourself:

            TestCycles8_10D.asm
            TestCycles8_15D.asm
            TestTime8_10D.asm
            TestTime8_15D.asm
           
            TestFloat8DR_10D.asm
            TestReal8DR_10D.asm           
            ...

    All these files are in Converter8 folder.

      note: the old Converter8 had a bug

      EDIT: see the first post

RuiLoureiro

#42
Hi
       i replaced Converter8 folder because i found one bug (the same) in some files
:t

RuiLoureiro

Hi all,
         i added a new folder Converter8. See the first post and read the last EDIT.
Good luck