--------------------------------------------------------------------------------
                      [NEW.....] VFP 9.0 FIX - THE NEW EXPRESSIONS FOR THE CALCULATE COMMAND
                                 January 2024
                 --------------------------------------------------------------------------------
                                     CCB



1. THE EXPRESSIONS FOR THE CALCULATE COMMAND (from dv_foxhelp9.chm):

     Visual FoxPro Advanced (10.0.0.0) Language Reference.
     CALCULATE Command

     Performs financial and statistical operations on fields in a table or on expressions involving fields.

     CALCULATE eExpressionList [Scope] [FOR lExpression1] [WHILE lExpression2]
     [TO VarList | TO ARRAY ArrayName] [NOOPTIMIZE] 
     [IN nWorkArea | cTableAlias]

     Parameters
     eExpressionList
     Specifies the expressions that can contain any combination of the following functions in Visual FoxPro 9:

     AVG(nExpression)
     Computes the arithmetic mean of nExpression.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     CNT() or COUNT()
     Returns the number of records in the table.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     MAX(eExpression)
     Returns the highest or latest value of eExpression. Within the MAX() clause, you can specify any character, date,
     datetime, numeric, float, integer, double, or currency field, or any expression using fields of these types.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     MIN(eExpression)
     Returns the lowest or earliest value of eExpression. Any character, date, datetime, numeric, float, integer, double,
     or currency field, or any valid expression using fields of these types, can be included in eExpression.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     NPV(nExpression1, nExpression2 [, nExpression3])
     Computes the net present value of a series of future cash flows discounted at a constant periodic interest rate.
     nExpression1 specifies the interest rate expressed as a decimal value. 
     nExpression2 specifies a field, field expression, or a numeric expression representing a series of cash flows.
     Each cash flow can be either positive or negative. In cases where nExpression2 is a field, the value for each record
     in the field is considered a cash flow. 
     nExpression3 specifies an optional initial investment. If the initial investment is not included, then the initial
     investment is assumed to occur at the end of the first period. This initial investment is the first record in the field
     and is negative to represent a cash outflow. 
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result. 

     STD(nExpression)
     Computes the standard deviation of nExpression. The standard deviation measures the degree to which the values of fields
     or expressions involving fields differ from the average of all the values. The smaller the standard deviation, the less
     the values vary from the average.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     SUM(nExpression)
     Totals the values of nExpression.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     VAR(nExpression)
     Computes the variance from the average of nExpression. The variance is the standard deviation squared.
     The smaller the variance, the less the values vary from the average.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     Specifies the expressions that can contain any combination of the following functions in Visual FoxPro Advanced:

     BAND(nExpression)
     Performs a bitwise AND operation on the values of nExpression.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     BOR(nExpression)
     Performs a bitwise OR operation on the values of nExpression.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     BXOR(nExpression)
     Performs a bitwise XOR operation on the values of nExpression.
     Only records meeting the Scope and/or optional FOR or WHILE conditions are included in the result.

     Functions in the expression list eExpressionList are separated by commas.
     They should not be confused with similarly named independent functions.
     For example, CALCULATE MIN() is not the same as MIN(). 

     The suggestion comes from John Ryan.


2. CAUSE:

     There are some BUGs in the following code.


3. RESOLUTION:

     We can write some code to fix the BUG.

     Label447020 ::
             push ebp                                                        ;0x00447020 :        55
             lea ebp ,  dword ptr [ esp + 0FFFFFD78h ]                       ;0x00447021 :        8dac2478fdffff
             sub esp , 06C4h                                                 ;0x00447028 :        81ecc4060000
             mov eax ,  dword ptr [ Data937090 ]                             ;0x0044702e :        a190709300
             mov  dword ptr [ ebp + 0284h ] , eax                            ;0x00447033 :        898584020000
             mov eax ,  dword ptr [ Data9370f8 ]                             ;0x00447039 :        a1f8709300
             mov  eax , dword ptr [eax]                                      ;0x0044703e :        8b00
             push ebx                                                        ;0x00447040 :        53
             push esi                                                        ;0x00447041 :        56
             xor esi , esi                                                   ;0x00447042 :        33f6
             cmp  dword ptr [ eax + 0118h ] , esi                            ;0x00447044 :        39b018010000
             push edi                                                        ;0x0044704a :        57
             mov  dword ptr [ ebp + 100 ] , esi                              ;0x0044704b :        897564
             mov  dword ptr [ ebp + 96 ] , esi                               ;0x0044704e :        897560
             jne Label608063                                                 ;0x00447051 :        0f850c101c00

     Label447057 ::
             mov  dword ptr [ ebp + 112 ] , esi                              ;0x00447057 :        897570

     Label44705a ::
             call Fun52dbd9                                                  ;0x0044705a :        e87a6b0e00
             mov  dword ptr [ ebp + 72 ] , eax                               ;0x0044705f :        894548
             lea edx ,  dword ptr [ ebp + 76 ]                               ;0x00447062 :        8d554c
             lea eax ,  dword ptr [ ebp - 60 ]                               ;0x00447065 :        8d45c4
             call Fun42c27f                                                  ;0x00447068 :        e81252feff
             push esi                                                        ;0x0044706d :        56
             push eax                                                        ;0x0044706e :        50
             call Fun42c2be                                                  ;0x0044706f :        e84a52feff
             cmp eax , esi                                                   ;0x00447074 :        3bc6
             pop ecx                                                         ;0x00447076 :        59
             pop ecx                                                         ;0x00447077 :        59
             mov  dword ptr [ ebp + 68 ] , eax                               ;0x00447078 :        894544
             jne Label44738b                                                 ;0x0044707b :        0f850a030000
             call Fun52d193                                                  ;0x00447081 :        e80d610e00
             mov  dword ptr [ ebp + 108 ] , eax                              ;0x00447086 :        89456c
             mov eax ,  dword ptr [ Data9370f8 ]                             ;0x00447089 :        a1f8709300
             mov  eax , dword ptr [eax]                                      ;0x0044708e :        8b00
             mov  eax , dword ptr [ eax + 0F0h ]                             ;0x00447090 :        8b80f0000000
             neg eax                                                         ;0x00447096 :        f7d8
             sbb eax , eax                                                   ;0x00447098 :        1bc0
             and eax , 0FFFFFFF8h                                            ;0x0044709a :        83e0f8
             add eax , 08h                                                   ;0x0044709d :        83c008
             pushd 0802h                                                     ;0x004470a0 :        6802080000
             or eax , 05h                                                    ;0x004470a5 :        83c805
             push eax                                                        ;0x004470a8 :        50
             lea esi ,  dword ptr [ ebp + 20 ]                               ;0x004470a9 :        8d7514
             call Fun52d2f6                                                  ;0x004470ac :        e845620e00
             mov  dword ptr [ ebp + 080h ] , eax                             ;0x004470b1 :        898580000000
             lea eax ,  dword ptr [ ebp + 96 ]                               ;0x004470b7 :        8d4560
             lea ecx ,  dword ptr [ ebp + 100 ]                              ;0x004470ba :        8d4d64
             lea edx ,  dword ptr [ ebp + 0FFFFFBC4h ]                       ;0x004470bd :        8d95c4fbffff
             call Fun44eb32                                                  ;0x004470c3 :        e86a7a0000
             and  dword ptr [ ebp + 124 ] , 00h                              ;0x004470c8 :        83657c00

     Label4470cc ::
             xor eax , eax                                                   ;0x004470cc :        33c0
             call Fun42c118                                                  ;0x004470ce :        e84550feff
             mov eax , esp                                                   ;0x004470d3 :        8bc4
             sub  eax , dword ptr [ Data9370c4 ]                             ;0x004470d5 :        2b05c4709300
             cmp eax , 058h                                                  ;0x004470db :        83f858
             jle Label60807b                                                 ;0x004470de :        0f8e970f1c00
             pushd 058h                                                      ;0x004470e4 :        6a58
             pop eax                                                         ;0x004470e6 :        58
             call Fun42c118                                                  ;0x004470e7 :        e82c50feff
             mov ebx , esp                                                   ;0x004470ec :        8bdc
             xor edi , edi                                                   ;0x004470ee :        33ff

     Label4470f0 ::
             mov  eax , dword ptr [ ebp + 124 ]                              ;0x004470f0 :        8b457c
             mov  ecx , dword ptr [ Data9393ac ]                             ;0x004470f3 :        8b0dac939300
             mov  dword ptr [ ebp + 4 * eax + 0FFFFFEC4h ] , ebx             ;0x004470f9 :        899c85c4feffff
             mov  al , byte ptr [ecx]                                        ;0x00447100 :        8a01
             inc ecx                                                         ;0x00447102 :        41
             inc ecx                                                         ;0x00447103 :        41
             cmp al , 0C0h                                                   ;0x00447104 :        3cc0
             mov  byte ptr [ebx] , al                                        ;0x00447106 :        8803
             mov  dword ptr [ Data9393ac ] , ecx                             ;0x00447108 :        890dac939300
             mov  byte ptr [ ebx + 1 ] , 00h                                 ;0x0044710e :        c6430100
             je Label608084                                                  ;0x00447112 :        0f846c0f1c00


     ;
     ;                 ---------------------------------------------------------------------
     ;                      VFP 9.0 FIX - THE NEW EXPRESSIONS FOR THE CALCULATE COMMAND
     ;                                  August 2019
     ;                 ---------------------------------------------------------------------
     ;                                     CCB
     ;
     ; The new expressions for the CALCULATE command: BAND(), BOR(), BXOR().
     ;
     ; 2019/8/15, by ccb
     ;

             cmp al , 0D1h
             je Label608143
             cmp al , 0D2h
             je Label608143
             cmp al , 0D3h
             je Label608143


             cmp al , 0BFh                                                   ;0x00447118 :        3cbf
             je Label608143                                                  ;0x0044711a :        0f8423101c00
             cmp al , 0BEh                                                   ;0x00447120 :        3cbe
             je Label608143                                                  ;0x00447122 :        0f841b101c00
             cmp al , 0BDh                                                   ;0x00447128 :        3cbd
             je Label4473ed                                                  ;0x0044712a :        0f84bd020000

     Label447130 ::
             push edi                                                        ;0x00447130 :        57
             lea eax ,  dword ptr [ ebp + 80 ]                               ;0x00447131 :        8d4550
             push eax                                                        ;0x00447134 :        50
             mov  dword ptr [ ebx + 80 ] , ecx                               ;0x00447135 :        894b50
             call Fun421d33                                                  ;0x00447138 :        e8f6abfdff
             mov  al , byte ptr [ ebp + 80 ]                                 ;0x0044713d :        8a4550
             cmp al , 059h                                                   ;0x00447140 :        3c59
             je Label44714c                                                  ;0x00447142 :        7408
             cmp al , 04Eh                                                   ;0x00447144 :        3c4e
             jne Label608112                                                 ;0x00447146 :        0f85c60f1c00

     Label44714c ::
             cmp  byte ptr [ ebp + 80 ] , 059h                               ;0x0044714c :        807d5059
             je Label60812c                                                  ;0x00447150 :        0f84d60f1c00

     Label447156 ::
             mov  eax , dword ptr [ ebp + 84 ]                               ;0x00447156 :        8b4554
             fldz                                                            ;0x00447159 :        d9ee
             add eax , 03h                                                   ;0x0044715b :        83c003
             fstp qword ptr [ ebx + 48 ]                                     ;0x0044715e :        dd5b30
             mov  word ptr [ ebx + 76 ] , ax                                 ;0x00447161 :        6689434c
             fldz                                                            ;0x00447165 :        d9ee
             xor eax , eax                                                   ;0x00447167 :        33c0
             lea edi ,  dword ptr [ ebx + 64 ]                               ;0x00447169 :        8d7b40
             stosd                                                           ;0x0044716c :        ab
             stosd                                                           ;0x0044716d :        ab
             fstp qword ptr [ ebx + 56 ]                                     ;0x0044716e :        dd5b38
             mov  eax , dword ptr [ ebx + 80 ]                               ;0x00447171 :        8b4350
             and  dword ptr [ ebx + 72 ] , 00h                               ;0x00447174 :        83634800
             mov dword ptr [ Data9393ac ] ,  eax                             ;0x00447178 :        a3ac939300
             call Fun522d3f                                                  ;0x0044717d :        e8bdbb0d00

     Label447182 ::
             inc  dword ptr [ Data9393ac ]                                   ;0x00447182 :        ff05ac939300
             mov eax ,  dword ptr [ Data9393ac ]                             ;0x00447188 :        a1ac939300
             inc  dword ptr [ ebp + 124 ]                                    ;0x0044718d :        ff457c
             cmp  byte ptr [eax] , 07h                                       ;0x00447190 :        803807
             je Label4425ba                                                  ;0x00447193 :        0f8421b4ffff

     Label447199 ::
             cmp  word ptr [ ebp + 100 ] , 00h                               ;0x00447199 :        66837d6400
             je Label4471ad                                                  ;0x0044719e :        740d
             movzx eax ,word ptr [ ebp + 100 ]                               ;0x004471a0 :        0fb74564
             cmp  eax , dword ptr [ ebp + 124 ]                              ;0x004471a4 :        3b457c
             jne Label6081c2                                                 ;0x004471a7 :        0f8515101c00

     Label4471ad ::
             cmp  dword ptr [ ebp + 080h ] , 00h                             ;0x004471ad :        83bd8000000000
             jne Label447284                                                 ;0x004471b4 :        0f85ca000000
             jmp Label44721b                                                 ;0x004471ba :        eb5f

     Label4471bc ::
             cmp  byte ptr [ ebx + 1 ] , 00h                                 ;0x004471bc :        807b0100
             jne Label6081cc                                                 ;0x004471c0 :        0f8506101c00
             mov eax , esi                                                   ;0x004471c6 :        8bc6
             call Fun53e878                                                  ;0x004471c8 :        e8ab760f00
             cmp  byte ptr [esi] , 04Eh                                      ;0x004471cd :        803e4e
             jne Label6082f2                                                 ;0x004471d0 :        0f851c111c00
             fld qword ptr [ esi + 16 ]                                      ;0x004471d6 :        dd4610
             mov  al , byte ptr [ebx]                                        ;0x004471d9 :        8a03
             cmp al , 0C1h                                                   ;0x004471db :        3cc1
             fld st(0)                                                       ;0x004471dd :        d9c0
             fadd qword ptr [ ebx + 48 ]                                     ;0x004471df :        dc4330
             fstp qword ptr [ ebx + 48 ]                                     ;0x004471e2 :        dd5b30
             je Label6082fc                                                  ;0x004471e5 :        0f8411111c00
             cmp al , 0C3h                                                   ;0x004471eb :        3cc3
             je Label6082fc                                                  ;0x004471ed :        0f8409111c00

     Label4471f3 ::
             fstp st(0)                                                      ;0x004471f3 :        ddd8

     Label4471f5 ::
             inc  dword ptr [ ebx + 72 ]                                     ;0x004471f5 :        ff4348

     Label4471f8 ::
             inc  dword ptr [ ebp + 080h ]                                   ;0x004471f8 :        ff8580000000
             mov  eax , dword ptr [ ebp + 080h ]                             ;0x004471fe :        8b8580000000
             cmp  eax , dword ptr [ ebp + 124 ]                              ;0x00447204 :        3b457c
             jb Label447228                                                  ;0x00447207 :        721f

     Label447209 ::
             call Fun52d126                                                  ;0x00447209 :        e8185f0e00
             lea eax ,  dword ptr [ ebp + 20 ]                               ;0x0044720e :        8d4514
             push eax                                                        ;0x00447211 :        50
             call Fun52cc46                                                  ;0x00447212 :        e82f5a0e00
             test eax , eax                                                  ;0x00447217 :        85c0
             jne Label447284                                                 ;0x00447219 :        7569

     Label44721b ::
             and  dword ptr [ ebp + 080h ] , 00h                             ;0x0044721b :        83a58000000000
             cmp  dword ptr [ ebp + 124 ] , 00h                              ;0x00447222 :        837d7c00
             jbe Label447209                                                 ;0x00447226 :        76e1

     Label447228 ::
             mov  eax , dword ptr [ ebp + 080h ]                             ;0x00447228 :        8b8580000000
             mov  ebx , dword ptr [ ebp + 4 * eax + 0FFFFFEC4h ]             ;0x0044722e :        8b9c85c4feffff
             cmp  byte ptr [ebx] , 0C4h                                      ;0x00447235 :        803bc4
             je Label4471f5                                                  ;0x00447238 :        74bb
             mov  eax , dword ptr [ ebx + 80 ]                               ;0x0044723a :        8b4350
             pushd 00h                                                       ;0x0044723d :        6a00
             mov dword ptr [ Data9393ac ] ,  eax                             ;0x0044723f :        a3ac939300
             call Fun420bce                                                  ;0x00447244 :        e88599fdff
             mov esi , eax                                                   ;0x00447249 :        8bf0
             mov  cl , byte ptr [esi]                                        ;0x0044724b :        8a0e
             cmp cl , 030h                                                   ;0x0044724d :        80f930
             mov  dword ptr [ ebp + 120 ] , esi                              ;0x00447250 :        897578
             je Label4471f8                                                  ;0x00447253 :        74a3
             mov  al , byte ptr [ebx]                                        ;0x00447255 :        8a03
             cmp al , 0BCh                                                   ;0x00447257 :        3cbc
             je Label4471bc                                                  ;0x00447259 :        0f845dffffff
             cmp al , 0BDh                                                   ;0x0044725f :        3cbd
             je Label4471f5                                                  ;0x00447261 :        7492
             jbe Label4471f8                                                 ;0x00447263 :        7693


     ;
     ;                 ---------------------------------------------------------------------
     ;                      VFP 9.0 FIX - THE NEW EXPRESSIONS FOR THE CALCULATE COMMAND
     ;                                  August 2019
     ;                 ---------------------------------------------------------------------
     ;                                     CCB
     ;
     ; The new expressions for the CALCULATE command: BAND(), BOR(), BXOR().
     ;
     ; 2019/8/15, by ccb
     ;

             cmp al , 0D1h
             je Label60826f
             cmp al , 0D2h
             je Label60826f
             cmp al , 0D3h
             je Label60826f


             cmp al , 0BFh                                                   ;0x00447265 :        3cbf
             jbe Label60826f                                                 ;0x00447267 :        0f8602101c00
             cmp al , 0C0h                                                   ;0x0044726d :        3cc0
             je Label6081f8                                                  ;0x0044726f :        0f84830f1c00
             jbe Label4471f8                                                 ;0x00447275 :        7681
             cmp al , 0C3h                                                   ;0x00447277 :        3cc3
             ja Label4471f8                                                  ;0x00447279 :        0f8779ffffff
             jmp Label4471bc                                                 ;0x0044727f :        e938ffffff

     Label447284 ::
             call Fun4214a4                                                  ;0x00447284 :        e81ba2fdff
             mov  ecx , dword ptr [ ebp + 108 ]                              ;0x00447289 :        8b4d6c
             pushd 03h                                                       ;0x0044728c :        6a03
             pop edx                                                         ;0x0044728e :        5a
             call Fun41ace3                                                  ;0x0044728f :        e84f3afdff
             xor ecx , ecx                                                   ;0x00447294 :        33c9
             call Fun425165                                                  ;0x00447296 :        e8cadefdff
             mov  eax , dword ptr [ ebp + 96 ]                               ;0x0044729b :        8b4560
             xor ebx , ebx                                                   ;0x0044729e :        33db
             cmp eax , ebx                                                   ;0x004472a0 :        3bc3
             jne Label60830b                                                 ;0x004472a2 :        0f8563101c00

     Label4472a8 ::
             cmp  dword ptr [ ebp + 124 ] , ebx                              ;0x004472a8 :        395d7c
             jbe Label4472e4                                                 ;0x004472ab :        7637

     Label4472ad ::
             mov  edi , dword ptr [ ebp + 4 * ebx + 0FFFFFEC4h ]             ;0x004472ad :        8bbc9dc4feffff
             mov  cl , byte ptr [edi]                                        ;0x004472b4 :        8a0f


     ;
     ;                 ---------------------------------------------------------------------
     ;                      VFP 9.0 FIX - THE NEW EXPRESSIONS FOR THE CALCULATE COMMAND
     ;                                  August 2019
     ;                 ---------------------------------------------------------------------
     ;                                     CCB
     ;
     ; The new expressions for the CALCULATE command: BAND(), BOR(), BXOR().
     ;
     ; 2019/8/15, by ccb
     ;

             cmp cl , 0D1h
             je Label6083eb
             cmp cl , 0D2h
             je Label6083eb
             cmp cl , 0D3h
             je Label6083eb


             movzx eax , cl                                                  ;0x004472b6 :        0fb6c1
             add eax , 0FFFFFF44h                                            ;0x004472b9 :        0544ffffff
             cmp eax , 08h                                                   ;0x004472be :        83f808
             ja Label4472de                                                  ;0x004472c1 :        771b
             jmp  dword ptr [ 4 * eax + offset DataPtr4473c9 ]                           ;0x004472c3 :        ff2485c9734400


4. APPLIES TO:

     VFP 10 (VFP Advanced)


5. REFERENCE WEBSITES:

     1, baiyujia.com:
     http://www.baiyujia.com
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix105.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix243.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix244.asp


6. OTHER:

     For reference only, there is no guarantees.

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