Microsoft KB Archive/172084: Difference between revisions

From BetaArchive Wiki
m (Text replacement - "<" to "<")
m (Text replacement - "&" to "&")
 
(One intermediate revision by the same user not shown)
Line 56: Line 56:


Use a custom routine that calculates the standard deviation. The following program accepts two parameters for the table and the field. Then it calculates the various sums and products of the fields before computing the standard deviation. Create a program called std and enter the following code:
Use a custom routine that calculates the standard deviation. The following program accepts two parameters for the table and the field. Then it calculates the various sums and products of the fields before computing the standard deviation. Create a program called std and enter the following code:
<pre class="codesample">  * Call this program by ?std(&quot;TableName&quot;,&quot;FieldName&quot;) or
<pre class="codesample">  * Call this program by ?std("TableName","FieldName") or
   * by assigning the result to a variable, y= std(&quot;TableName&quot;,&quot;FieldName&quot;)
   * by assigning the result to a variable, y= std("TableName","FieldName")
   *
   *
       PARAMETER mtable mfield
       PARAMETER mtable mfield
       SELECT SUM(&amp;mfield^2) FROM (mtable) INTO ARRAY yy
       SELECT SUM(&mfield^2) FROM (mtable) INTO ARRAY yy
       SELECT SUM(&amp;mfield)^2 FROM (mtable) INTO ARRAY zz
       SELECT SUM(&mfield)^2 FROM (mtable) INTO ARRAY zz
       SELECT COUNT(&amp;mfield) FROM (mtable) INTO ARRAY xx
       SELECT COUNT(&mfield) FROM (mtable) INTO ARRAY xx
       stdev=((xx*yy-zz)/xx^2)^.5
       stdev=((xx*yy-zz)/xx^2)^.5
       RETURN ROUND(stdev,12)
       RETURN ROUND(stdev,12)
                 </pre>
                 </pre>
If a table named values contains the field num, enter this command in the Command Window:
If a table named values contains the field num, enter this command in the Command Window:
<pre class="codesample">  ?std(&quot;values&quot;,&quot;num&quot;)
<pre class="codesample">  ?std("values","num")
                 </pre>
                 </pre>


Line 96: Line 96:
   SET SAFETY OFF
   SET SAFETY OFF
   SET DECIMALS TO 12
   SET DECIMALS TO 12
   CREATE TABLE stdresult (num N(15,8)) &amp;&amp;Table for result of calculation
   CREATE TABLE stdresult (num N(15,8)) &&Table for result of calculation
   APPEND BLANK
   APPEND BLANK
   CREATE TABLE stdtest (num N(15,8))  &amp;&amp;Table of values for calculation
   CREATE TABLE stdtest (num N(15,8))  &&Table of values for calculation
   FOR i = 1 TO 10
   FOR i = 1 TO 10
       INSERT INTO stdtest(num) VALUES (0.031)
       INSERT INTO stdtest(num) VALUES (0.031)
Line 104: Line 104:


   FOR i = 1 TO RECCOUNT()
   FOR i = 1 TO RECCOUNT()
       ?ALLTRIM(STR(i))+&quot; &quot;
       ?ALLTRIM(STR(i))+" "
       SET TALK OFF
       SET TALK OFF
       CALCULATE STD(num) FOR RECNO()<i TO nresult &amp;&amp; Comment this line &amp;
       CALCULATE STD(num) FOR RECNO()<i TO nresult && Comment this line &
                                                   &amp;&amp; the next line once
                                                   && the next line once
                                                   &amp;&amp; you uncomment the
                                                   && you uncomment the
                                                   &amp;&amp; commented lines below.
                                                   && commented lines below.


       ??nresult
       ??nresult


       *nresult=custstd('stdresult','num') &amp;&amp; Uncomment this line &amp; the next
       *nresult=custstd('stdresult','num') && Uncomment this line & the next
                                           &amp;&amp; line to compute &amp; display the
                                           && line to compute & display the
                                           &amp;&amp; standard deviation with a
                                           && standard deviation with a
                                           &amp;&amp; user-defined function.
                                           && user-defined function.


       *?nresult
       *?nresult
       SELECT stdresult
       SELECT stdresult
       REPLACE num WITH nresult  &amp;&amp;Overflow error on 10th iteration
       REPLACE num WITH nresult  &&Overflow error on 10th iteration
       SELECT stdtest
       SELECT stdtest
   ENDFOR
   ENDFOR
Line 130: Line 130:
   PROCEDURE custstd
   PROCEDURE custstd
   PARAMETER mtable mfield
   PARAMETER mtable mfield
   SELECT SUM(&amp;mfield^2) FROM (mtable) INTO ARRAY yy
   SELECT SUM(&mfield^2) FROM (mtable) INTO ARRAY yy
   SELECT SUM(&amp;mfield)^2 FROM (mtable) INTO ARRAY zz
   SELECT SUM(&mfield)^2 FROM (mtable) INTO ARRAY zz
   SELECT COUNT(&amp;mfield) FROM (mtable) INTO ARRAY xx
   SELECT COUNT(&mfield) FROM (mtable) INTO ARRAY xx
   stdev=((xx*yy-zz)/xx^2)^.5
   stdev=((xx*yy-zz)/xx^2)^.5
   RETURN ROUND(stdev,12)
   RETURN ROUND(stdev,12)

Latest revision as of 12:29, 21 July 2020

Article ID: 172084

Article Last Modified on 5/12/2003



APPLIES TO

  • Microsoft Visual FoxPro 3.0 Standard Edition
  • Microsoft Visual FoxPro 3.0b Standard Edition
  • Microsoft Visual FoxPro 5.0 Standard Edition
  • Microsoft Visual FoxPro 5.0a
  • Microsoft Visual FoxPro 3.0 for Macintosh



This article was previously published under Q172084

SYMPTOMS

When calculating the standard deviation using the CALCULATE STD() function, FoxPro can return results with a numeric overflow on certain numerical values over various ranges of records.

RESOLUTION

Use a custom routine that calculates the standard deviation. The following program accepts two parameters for the table and the field. Then it calculates the various sums and products of the fields before computing the standard deviation. Create a program called std and enter the following code:

   * Call this program by ?std("TableName","FieldName") or
   * by assigning the result to a variable, y= std("TableName","FieldName")
   *
      PARAMETER mtable mfield
      SELECT SUM(&mfield^2) FROM (mtable) INTO ARRAY yy
      SELECT SUM(&mfield)^2 FROM (mtable) INTO ARRAY zz
      SELECT COUNT(&mfield) FROM (mtable) INTO ARRAY xx
      stdev=((xx*yy-zz)/xx^2)^.5
      RETURN ROUND(stdev,12)
                

If a table named values contains the field num, enter this command in the Command Window:

   ?std("values","num")
                

STATUS

Microsoft is researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

The numeric overflow is generally observed when a table contains the same repeated real values over a broad range of records. For example, if a table contains 10 records and each record's value is 0.031, the CALCULATE STD() will produce an overflow. This can vary depending on the value and the number of records.

One way to detect that there was a numerical overflow is to display the result of the CALCULATE STD() to the desktop or in a WAIT WINDOW. If SET TALK is ON, the result will be displayed on the desktop automatically. If there is an overflow, all asterisks will be displayed. Also, if the result of the CALCULATE STD() is appended or replaced to a numerical field in a table, the following error may occur:

Numeric overflow. Data was lost.

Steps to Reproduce Behavior

Enter the following code in a program and run it:

   CLEAR
   SET SAFETY OFF
   SET DECIMALS TO 12
   CREATE TABLE stdresult (num N(15,8)) &&Table for result of calculation
   APPEND BLANK
   CREATE TABLE stdtest (num N(15,8))   &&Table of values for calculation
   FOR i = 1 TO 10
      INSERT INTO stdtest(num) VALUES (0.031)
   ENDFOR

   FOR i = 1 TO RECCOUNT()
      ?ALLTRIM(STR(i))+" "
      SET TALK OFF
      CALCULATE STD(num) FOR RECNO()<i TO nresult && Comment this line &
                                                  && the next line once
                                                  && you uncomment the
                                                  && commented lines below.

      ??nresult

      *nresult=custstd('stdresult','num') && Uncomment this line & the next
                                          && line to compute & display the
                                          && standard deviation with a
                                          && user-defined function.

      *?nresult
      SELECT stdresult
      REPLACE num WITH nresult   &&Overflow error on 10th iteration
      SELECT stdtest
   ENDFOR

   SET SAFETY ON
   SET TALK ON
   SET DECIMALS TO 2

   PROCEDURE custstd
   PARAMETER mtable mfield
   SELECT SUM(&mfield^2) FROM (mtable) INTO ARRAY yy
   SELECT SUM(&mfield)^2 FROM (mtable) INTO ARRAY zz
   SELECT COUNT(&mfield) FROM (mtable) INTO ARRAY xx
   stdev=((xx*yy-zz)/xx^2)^.5
   RETURN ROUND(stdev,12)
                

After running this code, the first nine iterations should be all zeroes. The calculation will be all asterisks and will produce the overflow error message on the REPLACE command.

Keywords: kbprb kbcode KB172084