### Author Topic: Converting real8 to string  (Read 16482 times)

#### jj2007

• Member
• Posts: 8731
• Assembler is fun ;-)
##### Re: Converting real8 to string
« Reply #15 on: May 01, 2013, 06:25:33 PM »
this is one of the finer points where Jochen and i disagree
the last digit does not to be correct to be considered "usable"

When I made my engineer, teachers told us to cut off at the last correct digit. I doubt that has changed...

#### RuiLoureiro

• Member
• Posts: 797
##### Re: Converting real8 to string
« Reply #16 on: May 01, 2013, 07:30:50 PM »
Hi ToutEnMasm

Quote
The address passed to the function must be STRFLOAT.strf and not STRFLOAT
Not very usable
Sorry, but it is very usable for all.

You have the complete code, so you can remove the length HERE:
Quote
@@:     EXPONENTREAL_8W

_finish:    mov      eax, edi
mov      edi, pRcl
sub      eax, edi

_exit0:     ;mov      dword ptr [edi-4], eax    ; <--- HERE
mov      byte ptr [edi+eax], 0

So you have the solution to use it as you want

Quote
It's the first time i see something working like that:
12 00 00 00 20 33 2e 31-34 31 35 39 32 36 35 33
conclusion: it's the first time you look at my code.
my library is full of this and i dont use things
like this: STRFLOAT STRUCT (e.g. structures).
I use EQU to do all my structures and i define
data byte by byte in the data section. Well i
use only my own library and not more.

To give you another example, a table of 20 pointers is this

dd 20         ; if we define this for unknown number of pointers
dd 0          ; <- no pointers in the table
_TblPtrX    dd 20 dup (?)

When i want to use it, i do something like this:

mov     ecx, [_TblPtrX-4]
jmp     _start
_loop:
mov     ebx, [_TblPtrX+ecx*4]   ; <-- ebx=pointer
;
; do something
;
_start: sub     ecx, 1
jns     short _loop

(note: the procs in my library follow this logic)

i think a macro may be used to define the buffer:

.data
dd ?
label  X dup (?)

#### RuiLoureiro

• Member
• Posts: 797
##### Re: Converting real8 to string
« Reply #17 on: May 01, 2013, 07:48:15 PM »
this is one of the finer points where Jochen and i disagree
the last digit does not to be correct to be considered "usable"

When I made my engineer, teachers told us to cut off at the last correct digit. I doubt that has changed...
Yes Jochen, if we have operands with x significant digits and
we do some set of operations, after that we lost significant digits
at the end and there is no solution to that. They are lost.
But in this case, the procedure that rounds it to 1 makes a little error
and we should know this and cut it. I dont see another solution.
If we use 2x significant digits, at the end, probably we have x
significant digits correct, depends on the operations, but x we should
have (probably they wasnt rounded).

#### dedndave

• Member
• Posts: 8808
• Still using Abacus 2.0
##### Re: Converting real8 to string
« Reply #18 on: May 01, 2013, 08:58:40 PM »
during a series of operations, you should retain as much precision as possible
while it's true that round-off errors accumulate, you are only making things worse if you continually throw away digits
when the final result is met, then you can round to some precision that is meaningful

in the real world, 6 or 7 digits is more than enough for most applications
the difference between 1.000001 and 1.000002 feet is very, very small and difficult to measure

there are cases where several more digits are useful
in electronics, i find these cases often in quantifying time or frequency, for example

#### jj2007

• Member
• Posts: 8731
• Assembler is fun ;-)
##### Re: Converting real8 to string
« Reply #19 on: May 01, 2013, 08:59:32 PM »
As Dave rightly writes, it's a "finer point". For an engineer, 1.2347 implies "the number is in the range 1.234650 to 1.23474999". From a viewpoint of numbers theory, and that's Dave's strong point, "usability" has a completely different meaning, so I consider his view legitimate but, of course, we agree to disagree

#### RuiLoureiro

• Member
• Posts: 797
##### Re: Converting real8 to string
« Reply #20 on: May 01, 2013, 09:25:04 PM »
Quote
you are only making things worse if you continually throw away digits
generaly, any calculator uses the same number of digits for all
operations, it doest use 10 digits for one operation and 8 for the
next

Quote
you can round to some precision that is meaningful
yes, meanningful is the question

Quote
For an engineer, 1.2347 implies "the number is in the range 1.234650 to 1.23474999"
Or for an error limit of 0.0001 that 1.2347 could be X, for instance,
with 5 decimal places

1.23465 < X < 1.23475

Well, the problem of that PI is only a problem of showing it in real8 because
FPU uses it and works in real10 and the value is the same.
« Last Edit: May 01, 2013, 11:05:27 PM by RuiLoureiro »

#### dedndave

• Member
• Posts: 8808
• Still using Abacus 2.0
##### Re: Converting real8 to string
« Reply #21 on: May 02, 2013, 01:17:45 AM »
something important to understand is that the value of Pi is known to many digits
the FPU gives you the REAL4, REAL8, or REAL10 value that it is capable of representing that is closest to Pi

when you evaluate that real number, don't expect to get digits that all match the value of Pi
the task of the routine is to evaluate the floating point value, as it is represented in the current format

#### RuiLoureiro

• Member
• Posts: 797
##### Re: Converting real8 to string
« Reply #22 on: May 02, 2013, 02:26:37 AM »
About what we show with real8 format
-------------------------------------------------

1. All numbers inside FPU are in real10 format.
We cannot load or operate in real4 or real8.
If we do that, first the real4 or real8 is
converted to real10 inside FPU. If we move
it to memory, there is a conversion to real4
or real8 format.
As far as i know.

EDIT: we may use real4 or real8 mode but it is useless.

2. When some procedure converts a real8 to
string and show it, what we see may be
the result of that procedure and not
the number itself inside FPU. Dont
forget that we need to do some operations
to get the number
and the string.

For instance, the real8 uses 52 bits+1
implied. So we should have only 16 digits.
Now see what happen when a procedure try
17 digits:

Quote
000_00000_00000001 = 4.940656458412465 e-324
000_FFFFF_FFFFFFFF = 2.2250738585072009e-308
7FF_00000_00000000 =+INFINITY
FFF_00000_00000000 =-INFINITY
7FE_FFFFF_FFFFFFFF = 1.7976931348623157e+308
001_00000_00000000 = 2.2250738585072014e-308
0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
0.1
0.2
0.2999999999999999
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat8DF  end test digits ***
-1.1000000000000001
-11.1
-111.09999999999999
-1111.0999999999999
-11111.1
-111111.10000000001
-1111111.1000000001
-11111111.1
-111111111.09999999
-1111111111.0999999
-11111111111.1
-111111111111.10001
-1111111111111.1001
-11111111111111.1
-111111111111111.09
-1111111111111111.1
-1.1111111111111112e+16
-1.1111111111111111e+17
-2.2000000000000002
-22.199999999999999
-222.19999999999999
-2222.1999999999998
-22222.200000000001
-222222.20000000001
-2222222.2000000002
-22222222.199999999
-222222222.19999999
-2222222222.1999998
-22222222222.200001
-222222222222.20001
-2222222222222.2002
-22222222222222.199
-222222222222222.19
-2222222222222222.2
-2.2222222222222224e+16
-2.2222222222222222e+17
-3.3
-33.3
-333.3
-3333.3
-33333.3
-333333.3
-3333333.3
-33333333.3
-333333333.3
-3333333333.3
-33333333333.3
-333333333333.3
-3333333333333.3
-33333333333333.3
-333333333333333.3
-3333333333333334
-3.333333333333333e+16
-3.333333333333333e+17
*** STOP - ConvertFloat8DF ***

now, the same procedure using 16 digits
and all seems to be perfect

Quote
000_00000_00000001 = 4.94065645841247 e-324
000_FFFFF_FFFFFFFF = 2.225073858507201e-308
7FF_00000_00000000 =+INFINITY
FFF_00000_00000000 =-INFINITY
7FE_FFFFF_FFFFFFFF = 1.797693134862316e+308
001_00000_00000000 = 2.225073858507201e-308
0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat8DF  end test digits ***
-1.1
-11.1
-111.1
-1111.1
-11111.1
-111111.1
-1111111.1
-11111111.1
-111111111.1
-1111111111.1
-11111111111.1
-111111111111.1
-1111111111111.1
-11111111111111.1
-111111111111111.1
-1.111111111111111e+15
-1.111111111111111e+16
-1.111111111111111e+17
-2.2
-22.2
-222.2
-2222.2
-22222.2
-222222.2
-2222222.2
-22222222.2
-222222222.2
-2222222222.2
-22222222222.2
-222222222222.2
-2222222222222.2
-22222222222222.2
-222222222222222.2
-2.222222222222222e+15
-2.222222222222223e+16
-2.222222222222222e+17
-3.3
-33.3
-333.3
-3333.3
-33333.3
-333333.3
-3333333.3
-33333333.3
-333333333.3
-3333333333.3
-33333333333.3
-333333333333.3
-3333333333333.3
-33333333333333.3
-333333333333333
-3.33333333333333e+15
-3.33333333333333e+16
-3.33333333333333e+17
*** STOP - ConvertFloat8DF ***
« Last Edit: May 02, 2013, 08:26:13 PM by RuiLoureiro »

#### qWord

• Member
• Posts: 1473
• The base type of a type is the type itself
##### Re: Converting real8 to string
« Reply #23 on: May 02, 2013, 02:39:02 AM »
We cannot load or operate in real4 or real8.
yes, of course we can do that.

If we do that, first the real4 or real8 is
converted to real10 inside FPU.
which means to zero extend the fraction bits.
MREAL macros - when you need floating point arithmetic while assembling!

#### RuiLoureiro

• Member
• Posts: 797
##### Re: Converting real8 to string
« Reply #24 on: May 02, 2013, 02:48:43 AM »
We cannot load or operate in real4 or real8.
yes, of course we can do that.
What are the instructions you use to do that
and does not imply a conversion ?
Do you know faddreal8 or something ?
May be it operates in real8 but i dont know.
For instance do you know how to load PI
in real8 ? I know fldpi only and it is real10
as far as i know.

#### qWord

• Member
• Posts: 1473
• The base type of a type is the type itself
##### Re: Converting real8 to string
« Reply #25 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()
MREAL macros - when you need floating point arithmetic while assembling!

#### jj2007

• Member
• Posts: 8731
• Assembler is fun ;-)
##### Re: Converting real8 to string
« Reply #26 on: May 02, 2013, 03:55:21 AM »
The effect can be quite significant:

NameA equ high precision        ; assign a descriptive name here
TestA proc
FpuSet MbNear64
mov ebx, AlgoLoops-1        ; loop e.g. 100x
align 4
.Repeat
fldpi
fld1
fdiv
fld1
fldpi
fmul        ; 13.011197054679151860
fstp st
dec ebx
.Until Sign?
ret
TestA endp
TestA_endp:

align 16
TestB_s:
NameB equ low precision        ; assign a descriptive name here
TestB proc
FpuSet MbNear24
mov ebx, AlgoLoops-1        ; loop e.g. 1000x
align 4
.Repeat
fldpi
fld1
fdiv
fld1
fldpi
fmul        ; 13.011198043823242190
fstp st
dec ebx
.Until Sign?
ret
TestB endp
TestB_endp:

Windows, for example, sets precision to 53 bits, afaik with the argument "that's faster than full precision". At least on my trusty old Celeron, the sequence above takes 7.1 cycles for both 64 and 24 bits precision:

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
loop overhead is approx. 2183/1000 cycles

7110    cycles for 1000 * high precision
7113    cycles for 1000 * low precision

7122    cycles for 1000 * high precision
7111    cycles for 1000 * low precision

#### ToutEnMasm

• Member
• Posts: 1190
##### Re: Converting real8 to string
« Reply #27 on: May 02, 2013, 04:08:58 AM »
The address passed to the function must be STRFLOAT.strf and not STRFLOAT
Not very usable
Quote
Sorry, but it is very usable for all.

Too much difficult ?
Here is a standard api call
Quote
Fa is a musical note to play with CL

#### qWord

• Member
• Posts: 1473
• The base type of a type is the type itself
##### Re: Converting real8 to string
« Reply #28 on: May 02, 2013, 04:21:57 AM »
At least on my trusty old Celeron, the sequence above takes 7.1 cycles for both 64 and 24 bits precision
not surprisingly, because the operations use the full 64 bit and than round to 53/24 bit.
It might be more interesting to see the effect on transcendental and logarithmic function. Especially because the precision of these functions seems to be implementation specific: For example, Intel guarantees an error below 1 ulp only for Pentium processors or newer (transcendental functions).

EDIT: transcendental and logarithmic functions are not affected by the precision control.
MREAL macros - when you need floating point arithmetic while assembling!

#### jj2007

• Member
• Posts: 8731
• Assembler is fun ;-)
##### Re: Converting real8 to string
« Reply #29 on: May 02, 2013, 04:31:51 AM »
not surprisingly, because the operations use the full 64 bit and than round to 53/24 bit.

So 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?

I can't see any reasonable argument for not using the full 80/64 bit mode...