Author Topic: Small favour needed, test precision with sprintf.  (Read 7987 times)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7537
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Small favour needed, test precision with sprintf.
« on: September 05, 2018, 02:14:34 PM »
I am testing the precision of the 64 bit MSVCRT version of sprintf. The default precision is 6 numbers after the decimal point but I have stretched it as far as I can get it on Win10 to about 11. I need the test done on Win7 64 or later to see if MSVCRT has remained the same over those OS versions. I would post the code but there are a number of things that have not been published yet.

This is the result I am getting on Win10 Professional.


    //////////////////////
    sprintf precision test
    \\\\\\\\\\\\\\\\\\\\\\

    Input  = 123456.1234567890123456
    Output = 123456.12345678901

    Press any key ....

hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

AW

  • Member
  • *****
  • Posts: 2583
  • Let's Make ASM Great Again!
Re: Small favour needed, test precision with sprintf.
« Reply #1 on: September 05, 2018, 03:36:05 PM »

Siekmanski

  • Member
  • *****
  • Posts: 2326
Re: Small favour needed, test precision with sprintf.
« Reply #2 on: September 05, 2018, 04:27:31 PM »
Win 8.1

Code: [Select]
    //////////////////////
    sprintf precision test
    \\\\\\\\\\\\\\\\\\\\\\

    Input  = 123456.1234567890123456
    Output = 123456.12345678901

    Press any key ....
Creative coders use backward thinking techniques as a strategy.

jj2007

  • Member
  • *****
  • Posts: 10543
  • Assembler is fun ;-)
    • MasmBasic
Re: Small favour needed, test precision with sprintf.
« Reply #3 on: September 05, 2018, 05:52:31 PM »
Same on Win7-64. It's a double, 16 digits.

Siekmanski

  • Member
  • *****
  • Posts: 2326
Re: Small favour needed, test precision with sprintf.
« Reply #4 on: September 06, 2018, 12:55:03 AM »
I tried to separate the integer and the fractional parts, but in 32 bit assembly the cvtpd2dq and cvtdq2pd instructions convert only 32 bit.
In 64 bit assembly 64 bits are converted.

At the moment I'm not able to run it in 64 bit assembly to test if we gain some resolution, probably not but....  :idea:
Maybe someone can test it in 64 bit assembly?

Code: [Select]
.data
align 16
Fabsmask   qword 7FFFFFFFFFFFFFFFh,7FFFFFFFFFFFFFFFh
float64bit real8 123456.1234567890123456
integer    real8 0.0
fraction   real8 0.0
szFloatNum db "%0.0f.%0.016f",0
szFloat64  db 64 dup (0)

.code
    movsd       xmm0,float64bit
    movsd       xmm2,xmm0
    cvtpd2dq    xmm1,xmm0     ; get rid of fractional part             
    cvtdq2pd    xmm1,xmm1     ; integer part
    subpd       xmm2,xmm1     ; subtract integer part from number to get fractional part
    andpd       xmm2,Fabsmask ; make fractional part absolute by removing sign bit
    movsd       integer,xmm1
    movsd       fraction,xmm2
   
    invoke      sprintf,addr szFloat64,addr szFloatNum,integer,fraction
    invoke      strlen,addr szFloat64
    lea         ecx,szFloat64
    movups      xmm0,[ecx+eax-16]
    movups      [ecx+eax-18],xmm0
    mov         byte ptr [ecx+eax-2],0

; print the szFloat64 string for the result.
; result with 32 bit assembly: 123456.1234567890060134
Creative coders use backward thinking techniques as a strategy.

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 7537
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Small favour needed, test precision with sprintf.
« Reply #5 on: September 06, 2018, 01:17:08 AM »
Marinus,

Like this ?

123456.1234567890060134
Press any key to continue...

I just plugged in your code into a 64 bit test piece, changed the 32 bit registers to 64 bit and used a 64 bit version of StrLen. Works fine.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .data
      align 16
      Fabsmask   qword 7FFFFFFFFFFFFFFFh,7FFFFFFFFFFFFFFFh
      float64bit real8 123456.1234567890123456
      integer    real8 0.0
      fraction   real8 0.0
      szFloatNum db "%0.0f.%0.016f",0
      szFloat64  db 64 dup (0)

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    movsd       xmm0,float64bit
    movsd       xmm2,xmm0
    cvtpd2dq    xmm1,xmm0     ; get rid of fractional part             
    cvtdq2pd    xmm1,xmm1     ; integer part
    subpd       xmm2,xmm1     ; subtract integer part from number to get fractional part
    andpd       xmm2,Fabsmask ; make fractional part absolute by removing sign bit
    movsd       integer,xmm1
    movsd       fraction,xmm2
   
    invoke      vc_sprintf,addr szFloat64,addr szFloatNum,integer,fraction
    invoke      StrLen,addr szFloat64
    lea         rcx,szFloat64
    movups      xmm0,[rcx+rax-16]
    movups      [rcx+rax-18],xmm0
    mov         byte ptr [rcx+rax-2],0

    conout      ptr$(szFloat64),lf

    waitkey
    .exit

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

nidud

  • Member
  • *****
  • Posts: 1980
    • https://github.com/nidud/asmc
Re: Small favour needed, test precision with sprintf.
« Reply #6 on: September 06, 2018, 02:08:56 AM »
Integer version.
Code: [Select]
    mov         rax,123456.1234567890123456
    movq        xmm0,rax
    cvtpd2dq    xmm1,xmm0
    movq        rdx,xmm1
    cvtdq2pd    xmm1,xmm1
    subpd       xmm0,xmm1
    mov         rax,10000000000.0
    movq        xmm1,rax
    mulpd       xmm0,xmm1
    cvtpd2dq    xmm0,xmm0
    movq        r8,xmm0

    printf("%I64d.%I64d\n", rdx, r8)

    123456.1234567890

Code: [Select]
    pcmpeqw xmm2,xmm2 ; Fabsmask
    psrlq   xmm2,1

HSE

  • Member
  • *****
  • Posts: 1377
  • <AMD>< 7-32>
Re: Small favour needed, test precision with sprintf.
« Reply #7 on: September 06, 2018, 03:30:59 AM »
Code: [Select]
xx\simd3>asmc -c simd3.asm
Asmc Macro Assembler Version 2.28.04
Copyright (C) The Asmc Contributors. All Rights Reserved.

 Assembling: simd3.asm

***********
ASCII build
***********

simd3.asm(47) : error A2070: invalid instruction operands

    "andpd       xmm2,Fabsmask ; make fractional part absolute by removing sign bit"

·······················································································································
xx\simd3>ml14 -c simd3.asm
Microsoft (R) Macro Assembler Version 14.00.23026.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: simd3.asm

***********
ASCII build
***********

xx\simd3>link simd3.obj /subsystem:console
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


xx\simd3>simd3
Hello Siemanski
123456.1234567890060134
Press any key to continue ...

Siekmanski

  • Member
  • *****
  • Posts: 2326
Re: Small favour needed, test precision with sprintf.
« Reply #8 on: September 06, 2018, 03:48:43 AM »
Thanks.
Useless attempt, no gain in resolution.  :biggrin:
Creative coders use backward thinking techniques as a strategy.

HSE

  • Member
  • *****
  • Posts: 1377
  • <AMD>< 7-32>
Re: Small favour needed, test precision with sprintf.
« Reply #9 on: September 06, 2018, 03:59:02 AM »
My previous post don't say it's 32bit, just showing AsmC error

Siekmanski

  • Member
  • *****
  • Posts: 2326
Re: Small favour needed, test precision with sprintf.
« Reply #10 on: September 06, 2018, 04:26:43 AM »
Hi HSE,

maybe this works,

andpd       xmm2,oword ptr Fabsmask
or
andpd       xmm2,xmmword ptr Fabsmask
Creative coders use backward thinking techniques as a strategy.

caballero

  • Member
  • *****
  • Posts: 1468
  • Matrix - Noah
    • abre ojos ensamblador
Re: Small favour needed, test precision with sprintf.
« Reply #11 on: September 06, 2018, 05:20:36 AM »
My result executing marinus.exe:

123456.1234567890060134
The logic of the error is hidden among the most unexpected lines of the program

HSE

  • Member
  • *****
  • Posts: 1377
  • <AMD>< 7-32>
Re: Small favour needed, test precision with sprintf.
« Reply #12 on: September 06, 2018, 05:25:46 AM »
Hi Siemanski!

Also work:

        Fabsmask   xmmword 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh (idem oword)


But where is MASM compatibility?

Siekmanski

  • Member
  • *****
  • Posts: 2326
Re: Small favour needed, test precision with sprintf.
« Reply #13 on: September 06, 2018, 06:09:16 AM »
Quote
But where is MASM compatibility?

What do you mean exactly?
Creative coders use backward thinking techniques as a strategy.

AW

  • Member
  • *****
  • Posts: 2583
  • Let's Make ASM Great Again!
Re: Small favour needed, test precision with sprintf.
« Reply #14 on: September 06, 2018, 06:22:12 AM »
I don't see any way of going there with SSE instructions.
Playing with FPU instructions we can obtain something like 123456.1234567890123444 which is closer.