---------------------------------------------------------------------------------------------------
                      [BUG/PRB.] ADJUST THE PRECISION OF THE FLOATING-POINT CONSTANTS FOR THE DIVISION OPERATOR
                                February 2024
                 ---------------------------------------------------------------------------------------------------
                                    CCB



1. BUG:

     There is a test program:

     *PROC testfloatingpointconstdivision

     SET DECIMALS TO 2
     ?INT(4294967295/16777216) && Displays 256 if SET("DECIMALS")<=3
     SET DECIMALS TO 10
     ?INT(4294967295/16777216) && Displays 255 if SET("DECIMALS")>=4

     RETURN

     * END OF PROC TESTFLOATINGPOINTCONSTDIVISION.

     We think they will display 255, but:
     ?INT(4294967295/16777216) && Displays 256 if SET("DECIMALS")<=3


2. CAUSE:

     In VFP 9.0 and earlier versions, the code:
     ?INT(4294967295/16777216)
     will be compiled to:
     17 00 02 F8 03 01 FC 43 FA 0A 00 00 00 E0 FF FF FF 6F 40 CC 38 FD FE
     --------------------------------------------------------------------
     VFP will calculate 4294967295/16777216 at compile time,
     the result is 255.99999994039535520 (0x406FFFFFFFE00000),
     the width of the floating-point number is 0x0A (dec: 10),
     the number of decimal places is 0x00 (dec: 0).

     For the details when VFP 9.0 calculates INT(4294967295/16777216):

     SET DECIMALS TO 2

       255. 9999 9994 0395 3552 0
     +   0. 0000 0500 0000 0000 0 (n=2, eps = 0.5*10^(-(n+3)) = 5.0000000000000004090E-06)
     ----------------------------
       256. 0000 0494 0395 3426 0

     So INT(4294967295/16777216) = 256 if SET("DECIMALS")=2.

     SET DECIMALS TO 10

       255. 9999 9994 0395 3552 0
     +   0. 0000 0000 0000 0500 0 (n=10, eps = 0.5*10^(-(n+3)) = 5.0000000000000001520E-14)
     ----------------------------
       255. 9999 9994 0395 4121 0

     So INT(4294967295/16777216) = 255 if SET("DECIMALS")=10.

     In VFP Advanced, the code:
     ?INT(4294967295/16777216)
     will be compiled to:
     17 00 02 F8 03 01 FC 43 FA 17 0C 00 00 E0 FF FF FF 6F 40 CC 38 FD FE
     --------------------------------------------------------------------
     VFP will calculate 4294967295/16777216 at compile time,
     the result is 255.99999994039535520 (0x406FFFFFFFE00000),
     the width of the floating-point number is 0x17 (dec: 23),
     the number of decimal places is 0x0C (dec: 12).

     For the details when VFP Advanced calculates INT(4294967295/16777216):

     SET DECIMALS TO 2

       255. 9999 9994 0395 3552 0
     +   0. 0000 0000 0000 0005 0 (n=12, eps = 0.5*10^(-(n+3)) = 5.0000000000000001820E-16)
     ----------------------------
       255. 9999 9994 0395 3552 0

     So INT(4294967295/16777216) = 255 if SET("DECIMALS")=2.

     SET DECIMALS TO 10

       255. 9999 9994 0395 3552 0
     +   0. 0000 0000 0000 0005 0 (n=12, eps = 0.5*10^(-(n+3)) = 5.0000000000000001520E-16)
     ----------------------------
       255. 9999 9994 0395 3552 0

     So INT(4294967295/16777216) = 255 if SET("DECIMALS")=10.

     There are some BUGs in the following code.


3. RESOLUTION:

     We can write some code to fix the BUG.

     Label8475c9 ::
             cmp bl , 0FAh                                                   ;0x008475c9 :        80fbfa
             je Label8475db                                                  ;0x008475cc :        740d
             fild dword ptr [edi]                                            ;0x008475ce :        db07
             mov  byte ptr [ edi + 16 ] , 0FAh                               ;0x008475d0 :        c64710fa
             mov  byte ptr [ edi + 18 ] , 00h                                ;0x008475d4 :        c6471200
             fstp qword ptr [ edi + 8 ]                                      ;0x008475d8 :        dd5f08

     Label8475db ::
             cmp  byte ptr [ ecx + 16 ] , 0FAh                               ;0x008475db :        807910fa
             je Label8475ee                                                  ;0x008475df :        740d
             fild dword ptr [ecx]                                            ;0x008475e1 :        db01
             mov  byte ptr [ ecx + 16 ] , 0FAh                               ;0x008475e3 :        c64110fa
             mov  byte ptr [ ecx + 18 ] , 00h                                ;0x008475e7 :        c6411200
             fstp qword ptr [ ecx + 8 ]                                      ;0x008475eb :        dd5908

     Label8475ee ::
             fld qword ptr [ Data91fbc8 ]                                    ;0x008475ee :        dd05c8fb9100
             fld qword ptr [ ecx + 8 ]                                       ;0x008475f4 :        dd4108
             fucompp                                                         ;0x008475f7 :        dae9
             fstsw ax                                                        ;0x008475f9 :        dfe0
             test  byte ptr ah , 044h                                        ;0x008475fb :        f6c444
             jnp Label8474df                                                 ;0x008475fe :        0f8bdbfeffff
             fld qword ptr [ edi + 8 ]                                       ;0x00847604 :        dd4708
             mov  dword ptr [ Data93cc80 ] , 00h                             ;0x00847607 :        c70580cc930000000000
             fdiv qword ptr [ ecx + 8 ]                                      ;0x00847611 :        dc7108
             mov eax ,  dword ptr [ Data93cc80 ]                             ;0x00847614 :        a180cc9300
             test eax , eax                                                  ;0x00847619 :        85c0
             fstp qword ptr [ edi + 8 ]                                      ;0x0084761b :        dd5f08
             jne Label8474df                                                 ;0x0084761e :        0f85bbfeffff
             mov  al , byte ptr [ edi + 18 ]                                 ;0x00847624 :        8a4712
             test al , al                                                    ;0x00847627 :        84c0
             je Label847638                                                  ;0x00847629 :        740d
             mov  bl , byte ptr [ edi + 17 ]                                 ;0x0084762b :        8a5f11
             or dl , 0FFh                                                    ;0x0084762e :        80caff
             sub dl , al                                                     ;0x00847631 :        2ad0
             add bl , dl                                                     ;0x00847633 :        02da
             mov  byte ptr [ edi + 17 ] , bl                                 ;0x00847635 :        885f11

     Label847638 ::
             movzx ecx ,byte ptr [ ecx + 18 ]                                ;0x00847638 :        0fb64912
             movzx edx , al                                                  ;0x0084763c :        0fb6d0
             lea eax ,  dword ptr [ edx + ecx ]                              ;0x0084763f :        8d040a


     ;
     ;                 ------------------------------------------------------------------------------------------------------
     ;                      VFP 9.0 FIX - ADJUST THE PRECISION OF THE FLOATING-POINT CONSTANTS FOR THE DIVISION OPERATOR
     ;                                February 2024
     ;                 ------------------------------------------------------------------------------------------------------
     ;                                     CCB
     ;
     ; Adjust the precision of the floating-point constants for the division operator.
     ;
     ; 2024/2/4, by ccb
     ;

             cmp dword ptr vfpa_sys9147_data,00h
             je Label847642

             sub esp , 08h
             fld qword ptr [ edi + 8 ]

             fld st(0)
             fabs
             fldlg2
             fxch st(1)
             fyl2x

             fld st(0)
             fistp dword ptr [ esp ]
             mov edx,dword ptr [ esp ]
             cmp edx,80000000h
             je Label847640
             and edx,80000000h
             test edx,edx
             jne Label847640

             mov edx,0
             IFDEF RAX
             push esi
             lea esi ,  dword ptr [ Data922438 ]
             fadd qword ptr [ 8 * edx + esi ]
             pop esi
             ELSE
             fadd qword ptr [ 8 * edx + offset Data922438 ]
             ENDIF

             mov edx,0Ah
             IFDEF RAX
             push esi
             lea esi ,  dword ptr [ Data922438 ]
             fadd qword ptr [ 8 * edx + esi ]
             pop esi
             ELSE
             fadd qword ptr [ 8 * edx + offset Data922438 ]
             ENDIF

             fistp dword ptr [ esp ]
             mov edx,0Fh
             sub edx,dword ptr [ esp ]
             cmp edx,0
             jl Label847641
             cmp edx,0Fh
             jg Label847641

             cmp edx,eax
             jle Label847641
             mov eax,edx
             jmp Label847641

     Label847640 ::
             fstp st(0)
             mov edx,0Fh
             cmp edx,eax
             jle Label847641
             mov eax,edx
             mov bl,01h
             mov byte ptr [ edi + 17 ],bl
             jmp Label847641

     Label847641 ::
             fstp st(0)
             add esp , 08h
             jmp Label847642


     Label847642 ::
             cmp eax , 012h                                                  ;0x00847642 :        83f812
             jl Label84764c                                                  ;0x00847645 :        7c05
             mov eax , 012h                                                  ;0x00847647 :        b812000000

     Label84764c ::
             fld qword ptr [ edi + 8 ]                                       ;0x0084764c :        dd4708
             sub esp , 08h                                                   ;0x0084764f :        83ec08
             fstp qword ptr [ esp ]                                          ;0x00847652 :        dd1c24
             mov  byte ptr [ edi + 18 ] , al                                 ;0x00847655 :        884712
             call  _finite                                     ;0x00847658 :        ff15ec789100
             add esp , 08h                                                   ;0x0084765e :        83c408
             test eax , eax                                                  ;0x00847661 :        85c0
             je Label84771b                                                  ;0x00847663 :        0f84b2000000
             fld qword ptr [ Data91fbc8 ]                                    ;0x00847669 :        dd05c8fb9100
             fld qword ptr [ edi + 8 ]                                       ;0x0084766f :        dd4708
             fucompp                                                         ;0x00847672 :        dae9
             fstsw ax                                                        ;0x00847674 :        dfe0
             test  byte ptr ah , 044h                                        ;0x00847676 :        f6c444
             jnp Label84771b                                                 ;0x00847679 :        0f8b9c000000
             fld qword ptr [ edi + 8 ]                                       ;0x0084767f :        dd4708
             fabs                                                            ;0x00847682 :        d9e1
             fldlg2                                                          ;0x00847684 :        d9ec
             fxch st(1)                                                      ;0x00847686 :        d9c9
             fyl2x                                                           ;0x00847688 :        d9f1
             fcom qword ptr [ Data91fbc8 ]                                   ;0x0084768a :        dc15c8fb9100
             fstsw ax                                                        ;0x00847690 :        dfe0
             test  byte ptr ah , 01h                                         ;0x00847692 :        f6c401
             jne Label8476ae                                                 ;0x00847695 :        7517
             sub esp , 08h                                                   ;0x00847697 :        83ec08
             fstp qword ptr [ esp ]                                          ;0x0084769a :        dd1c24
             call  floor                                       ;0x0084769d :        ff15a0799100
             fadd qword ptr [ Data921e20 ]                                   ;0x008476a3 :        dc05201e9200
             add esp , 08h                                                   ;0x008476a9 :        83c408
             jmp Label8476b6                                                 ;0x008476ac :        eb08


4. APPLIES TO:

     VFP 6.0.8167.0
     VFP 6.0.8961.0 (SP5)

     VFP 7.0.0.9262
     VFP 7.0.0.9465 (SP1)

     VFP 8.0.0.2521
     VFP 8.0.0.3117 (SP1)

     VFP 9.0.0.2412
     VFP 9.0.0.3504 (SP1)
     VFP 9.0.0.4611 (SP2)
     VFP 9.0.0.5015 (SP2)
     VFP 9.0.0.5411 (SP2)
     VFP 9.0.0.5721 (SP2)
     VFP 9.0.0.5815 (SP2)
     VFP 9.0.0.6303 (SP2)
     VFP 9.0.0.6602 (SP2)
     VFP 9.0.0.7423 (SP2)

     The bug has been fixed in VFP Advanced.


5. REFERENCE WEBSITES:

     1, baiyujia.com:
     http://www.baiyujia.com
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix305.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix23.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix24.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix97.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix98.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix123.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix124.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix255.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix256.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix257.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix258.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix259.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix260.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix303.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix304.asp


6. OTHER:

     For reference only, there is no guarantees.

     Any questions or suggestions, please send me an email at ccb2000@163.com.