PureBytes Links
Trading Reference Links
|
Guy:
This is a direct cut and paste from a Microsoft Product Support Services web
site. All I am saying is that I understand your frustration from precision
errors. I am also saying that virtually all software suffers from the same
problem. I provide this in hopes that everyone will realize that floating
point errors are not unique to MetaStock.
http://support.microsoft.com/support/kb/articles/Q196/6/52.asp
----------------------------------------------------------------------
Floating Point Limitations
All of the rounding implementations presented here use the double data type,
which can represent approximately 15 decimal digits.
Since not all fractional values can be expressed exactly, you might get
unexpected results because the display value does not match the stored
value.
For example, the number 2.25 might be stored internally as 2.2499999...,
which would round down with arithmetic rounding, instead of up as you might
expect. Also, the more calculations a number is put through, the greater
possibility that the stored binary value will deviate from the ideal decimal
value.
-----------------------------------------------------------------------
Also below is another cut and paste from Microsoft
http://support.microsoft.com/support/kb/articles/Q125/0/56.ASP
There are many situations in which precision, rounding, and accuracy in
floating-point calculations can work to generate results that are surprising
to the programmer. There are four general rules that should be followed:
In a calculation involving both single and double precision, the result will
not usually be any more accurate than single precision. If double precision
is required, be certain all terms in the calculation, including constants,
are specified in double precision.
Never assume that a simple numeric value is accurately represented in the
computer. Most floating-point values can't be precisely represented as a
finite binary value. For example .1 is .0001100110011... in binary (it
repeats forever), so it can't be represented with complete accuracy on a
computer using binary arithmetic, which includes all PCs.
Never assume that the result is accurate to the last decimal place. There
are always small differences between the "true" answer and what can be
calculated with the finite precision of any floating point processing unit.
Never compare two floating-point values to see if they are equal or not-
equal. This is a corollary to rule 3. There are almost always going to be
small differences between numbers that "should" be equal. Instead, always
check to see if the numbers are nearly equal. In other words, check to see
if the difference between them is very small or insignificant.
------------------------------------------------------------------------
What I have said all along is that we chose not to mask the errors (by
assuming how much precision our customers want) because our users have such
a wide range of precision that they require. We provided the tools for our
users to determine their own precision in calculations. You can get
COMPLETELY accurate results from MetaStock but you have to do some extra
programming in the formula language to get it. We chose simply to make no
assumptions about how much precision our formula writing users would
require. We gave them the tools to apply precision for themselves.
Ken Hunt
Programming Manager
Equis International
-----Original Message-----
From: Guy Tann [mailto:grt@xxxxxxxxxxxx]
Sent: Tuesday, September 05, 2000 12:22 PM
To: metastock@xxxxxxxxxxxxx
Subject: RE: First calculation problem
Ken,
I understand what you're saying completely. You have missing my point
entirely.
As a user, I really don't care how the numbers are represented internally.
I just care that the answers are CORRECT. Again, in order to reemphasize,
you have missed my point entirely. The other software I have, including
several different programming languages, all manage to provide the correct
results, regardless of how they're represented internally. If, as you say,
the other software only modified the results before displaying them or
played some other internal game and still maintained the single precision
result internally, then all of their subsequent calculations would be off by
the same amount as MS (0.2) for each calculation, since they would be using
this internal, erroneous result. My point that you're missing, is that
these other languages, regardless of precision, are able to not only display
the correct result (and I really don't care how they do it), they are also
able to use that correct result internally in subsequent calculations, which
MS DOESN'T!
So, I guess I still don't understand your point. Having majors in
Mathematics, Statistics, and Economics, and having almost 40 years
experience programming (my first job was as a Systems Engineer at IBM), this
is very frustrating. While I admit to getting older, I still haven't
reached my dad's 91 years yet. My 10 year old, my brother and I, and my
"old man" (who refuses to use MS because of this) still can't understand how
every other package or language we have is able to subtract two numbers and
use the results in further calculations without a problem regardless of what
is taking place internally. Notice I'm not referring to just what is
displayed.
If we were talking theory or some esoteric mathematical methodology, I
understand that 2.379999999 can accurately approximate 2.38, a real world
number. In calculus and statistics, I'm used to getting close but not exact
results as n goes from 1 and approaches infinity. We're talking subtraction
and 2.379999999 is NOT the correct result of the calculation 14.89 - 12.51 =
2.38, regardless of whatever planet you're on. More importantly, any
further calculations that use the result of that first subtraction should
use 2.38 and not 2.379999999! Again, all of my other software has managed
to figure out that they not only need to display the correct answer but that
they also have to use that correct answer in further calculations.
What about this is so hard to understand?
Regardless of precision, any language that purports to provide basic
arithmetic capabilities should be required to provide correct results.
Again, this internal representation of numbers is not the issue here; it's
what you display and what you use internally in subsequent calculations.
The bottom line is, MS contains a major flaw insofar as it is unable to
perform simple arithmetic and use the results in subsequent calculations.
You should put a warning on MS stating this, much like the warning on
cigarettes. Something like, even though MS uses single precision arithmetic
like Excel and others, it is unable to duplicate their results, which may
affect your financial health. Seriously, can you see what I'm saying? What
you display and how you display it is symptomatic of a more invasive
problem. What you display is also what you use in your further
calculations, and since you have calculated an incorrect result, all of your
subsequent calculations will be wrong. This is the problem, and in my mind,
a very significant one.
Guy
" When I die, I want to go peacefully like my grandfather did, in his sleep.
Not yelling and screaming like the passengers in his car."
-----Original Message-----
From: owner-metastock@xxxxxxxxxxxxx [mailto:owner-metastock@xxxxxxxxxxxxx]On
Behalf Of PD Manager
Sent: Tuesday, September 05, 2000 7:41 AM
To: 'metastock@xxxxxxxxxxxxx'
Subject: RE: First calculation problem
Guy:
Regardless of where the numbers come from (download, keyboard or wherever)
the error occurs when the numbers are translated from the ASCII
representation and stored in the machine. The other software packages
suffer from the same problem. What they have chosen to do is to
automatically mask the problem by truncating the OUTPUT before display. I
assure you that INTERNALLY, the numbers are the same. MetaStock does not
modify the output numbers. Regardless of the software package, the internal
storage is a HARDWARE approximation of a floating point number. Some
software packages simply truncate and round the output BEFORE DISPLAY to
mask the problem away from the user. The approximation and the associated
accuracy problems are still there.
Some software packages will use double precision floating point numbers to
help improve the accuracy of floating point representation. As I said, this
comes at the cost of double the memory requirements.
Ken Hunt
Programming Manager
Equis International
-----Original Message-----
From: Guy Tann [mailto:grt@xxxxxxxxxxxx]
Sent: Monday, September 04, 2000 6:28 PM
To: metastock@xxxxxxxxxxxxx
Subject: RE: First calculation problem
Ken,
Sorry for the delay, but my DSL modem crapped out and then I was visiting
Murder City until today.
I wasn't typing anything into the computer. I used Equis' Downloader and
Reuter's data service to download my data. I then use MS to massage it.
Interestingly, TAS uses the Downloader data as well without any of these
problems. Using OLE to access the data in Excel works properly as well. It
appears that these other software packages manage to keep track of the
correct number of decimal places, whereas MS just sort of goes with the flow
and takes whatever it might find stored. I really don't care as long as I
know that accuracy isn't one of MS' strong suits. I can understand your
points, but in working with many programming languages, they all manage to
do something to keep track of significant digits without barfing. Again, if
I was doing anything complex, I could understand your point completely, but
the inability to subtract two numbers and consistently come up with the
correct answer is still hard for me to fathom.
Anyway, here is a sample of some of the code I've had to use to get around
this in one instance. By the way, none of my other programming languages or
Excel require these mechanizations. It appears that MS was designed as a
charting or graphics program with computational capabilities added as an
afterthought. What we need to remember is that if we want to use it as
such, we'll need to work around its deficiencies ourselves.
COMN0:= C - COMMODLOW; {simple subtraction of C - L}
COMN:= PREC( If( COMN0 > 0 , (COMN0+.005), If( COMN0 < 0 , (COMN0 - .005 ) ,
COMN0 )) , 2 ); {needed to fix MS inability to maintain significant digits}
COMN1:= COMN / COMAR; {simple divide}
COMN2:= COMN1 - .5; {Simple subtraction}
COMN3:= COMN2 * 2; {simple multiplication}
COMN3R:= If( COMN3 > 0 , (COMN3 + .00005 ) ,
If( COMN3 < 0 , (COMN3 - .00005 ) ,
0 ) ); {rounding to 4 decimal places performed manually}
COMN4:= ( PREC( COMN3R, 4 ) * 10); {take answer to 4 decimals and multiply
by 10}
COMN5:= If( COMN4 > 0 , ( COMN4 ) + .5 , If( COMN4 < 0 , ( COMN4 ) - .5 ,
( COMN4 ) )); {round to nearest whole number}
COMY:= Int( COMN5 ); {store integer}
This does work, albeit in a slightly confused manner and requires 8 more
variables than it should. Using this fixed the one erroneous calculation I
had and let me move on for further testing.
OTOH, I am now working on trying to get the Ref() function to work per the
manual and will try to get some time to spend on it tonight if I can stay
awake. I was up at 4AM Detroit time (1AM local time) and have over 400
e-mails to wade through since 8/29 (most of which I deleted).
Guy
" When I die, I want to go peacefully like my grandfather did, in his sleep.
Not yelling and screaming like the passengers in his car."
-----Original Message-----
From: owner-metastock@xxxxxxxxxxxxx [mailto:owner-metastock@xxxxxxxxxxxxx]On
Behalf Of PD Manager
Sent: Tuesday, August 29, 2000 10:05 AM
To: 'metastock@xxxxxxxxxxxxx'
Subject: RE: First calculation problem
Guy:
The precision error occurs as soon as the number is stored in your computer.
If you are typing a number into a computer (such as 12.1), as soon as that
number is stored in a single precision floating point number in your
computer, the precision error is there. The number is already stored as an
approximation. This is a CPU / hardware issue and is not related to the
software itself.
Most software will mask this error by doing rounding of a floating point
number before it is displayed. In the case of the 1469.3999999, if you ask
a computer to display that number with two digits to the right of the
decimal point, rounding occurs and you will see 1469.40, but the number is
actually stored in the computer as 1469.3999999. This is true even if you
entered a number at the keyboard (or downloaded the number or read it from
some other source) that was 1469.40.
The difference between MetaStock and your other packages is that the other
software is performing the rounding before the results are displayed on the
screen. MetaStock is not doing this and is displaying the numbers out to
the maximum possible length. I assure you that if other software packages
are displaying 1469.40, the internal representation is actually
1469.3999999. The approximation and actual storage of the numbers is a
function of the CPU hardware and not the software package itself.
Ken Hunt
Programming Manager
Equis International
-----Original Message-----
From: Guy Tann [mailto:grt@xxxxxxxxxxxx]
Sent: Monday, August 28, 2000 12:34 PM
To: metastock@xxxxxxxxxxxxx
Subject: RE: First calculation problem
Ken,
I guess I still don't understand what's happening here.
These numbers were downloaded from Reuters and were stored in the O, H, L, C
data arrays, all handled internally by Equis. My assumption is that these
numbers were downloaded properly and that they contain only the two decimal
places shown in the data and in the data window. Going out and looking at
the numbers in Downloader and in the related Chart supports that assumption.
Is that an invalid assumption? These numbers only have two decimal places
to begin with. Did MS somehow managed to "modify" the original input and
store them as something like 1469.3999999?
If that's the case, then using Precision in order to insure that simple
arithmetic calculations to maintain the two decimals places appears to be a
requirement.
Generally, there are very few problems occurring, but they are sufficient to
throw off some of our results.
We have these calculations running in Clipper, Excel, COBOL, and TAS without
problems.
We only have three different levels of precision in our system and they are
0, 2, and 4. We either use the Rnd() function or in cases like the one I'm
working on right now, manually code our own rounding.
Guy
" When I die, I want to go peacefully like my grandfather did, in his sleep.
Not yelling and screaming like the passengers in his car."
-----Original Message-----
From: owner-metastock@xxxxxxxxxxxxx [mailto:owner-metastock@xxxxxxxxxxxxx]On
Behalf Of PD Manager
Sent: Monday, August 28, 2000 8:15 AM
To: 'metastock@xxxxxxxxxxxxx'
Subject: RE: First calculation problem
Isn't programming with floating point numbers fun? <g>
Floating point errors tend to compound as more calculations are performed.
I could write an entire book on the subject (I'm sure there are books
written on just this subject). Typically, floating point numbers are
guaranteed to have 6-7 digits of precision. When you start doing
mathematical operations on these numbers, there are times when some of these
strange issues will creep in.
What I have found is that you should use the precision function only if you
are trying to compare floating point numbers. Otherwise just stick with the
standard calculations.
What is amazing is that although your numbers look good to start with
(1486.20 and 1469.40) the error is probably already there. The actual
numbers stored in the computer may already be something like (1486.20000001
or 1469.3999999). Usually when these numbers are prepared for output
(display or printed) the software will perform rounding to get them to look
like the numbers you entered. When you perform a mathematical operation on
these numbers, the error becomes more apparent so that the rounding before
output didn't make your result look correct.
Virtually any computer that stored floating point numbers has this problem.
I worked on flight simulations for several years and the only way we could
get around the problem was to do EVERYTHING in integer math and keep track
of assumed decimal points.
Ken Hunt
Programming Manager
Equis International
-----Original Message-----
From: Guy Tann [mailto:grt@xxxxxxxxxxxx]
Sent: Sunday, August 27, 2000 1:50 AM
To: metastock@xxxxxxxxxxxxx
Subject: RE: First calculation problem
Ken,
Are you saying that I need to add the prec() function to each one of my
variable calculations? Does this problem compound when building systems
using calculations upon calculations or will the prec() function used at
each level take care of the problem?
Guy
Never be afraid to try something new. Remember, amateurs built the ark,
professionals built the Titanic.
-----Original Message-----
From: owner-metastock@xxxxxxxxxxxxx [mailto:owner-metastock@xxxxxxxxxxxxx]On
Behalf Of PD Manager
Sent: Friday, August 25, 2000 7:35 AM
To: 'metastock@xxxxxxxxxxxxx'
Subject: RE: First calculation problem
MetaStock does indeed use single precision floating point numbers. As you
mentioned, going to double precision would literally double the memory
requirements for data storage for charts and would also slow down
calculations. When you get into mathematical calculations, however, going
to double precision doesn't necessarily make the problem better. PC
computer hardware still cannot accurately store a number as simple as 0.1
whether you are using single or double precision. It is stored as an
approximation. When it comes to floating point numbers, the hardware can
really only accurately store fractional numbers that are powers of two (1/2,
1/4, 1/8, 1/16 etc).
Other software packages suffer from the same problem (including VB and
Excel) although some manage to mask it better than others. If you don't
believe this, I can submit a set of "simple" calculations that will cause
Excel to show precision errors also.
Some software packages will use other methods to store and/or calculate
floating point numbers. This usually involves something like BCD encoding
or some type of integer encoded fixed point real numbers. While this
ultimately solves the precision problem, it has other problems with speed of
calculations as well as a reduced ability to store large or very small
numbers.
We have always been aware of this issue and that is why we added the
precision function to the formula language. It was put there in an attempt
to help those writing formulas to work with the precision they needed.
Ken Hunt
Programming Manager
Equis International
-----Original Message-----
From: Kent Rollins [mailto:kentr@xxxxxxxxxxxxxx]
Sent: Friday, August 25, 2000 12:40 AM
To: metastock@xxxxxxxxxxxxx
Subject: Re: First calculation problem
Looks like you may have hit the old single-precision problem. PCs basically
have 3 native ways of storing floating point numbers: single-precision (4
bytes), double-precision (8 bytes), and long double (10 bytes). The problem
is that each one of these representations has a limited number of "numbers"
that it can represent and from time to time you will hit a calculation that
reveals this limitation in all it's splendor. Single-precision floats can
represent approximately 4 billion different numbers. That's a lot until you
consider that between 0 and 1 there are an infinite number of floating point
numbers. Double-precision has many, many more number that it can represent
(4 billion times 4 billion) and you RARELY see the kind of error you have
hit when you are dealing with numbers on the scale of 1486 with only 2
places of precision. That leads me to suspect that Equis is using
single-precision numbers for these calculations (Omega does the same thing).
Saves memory, SLIGHTLY faster in computation, loses precision. There is
really no good reason for using singles in an app like this and there is a
(now obvious) good reason not to. I would scream and yell at Equis. Tell
Little Guy that if he convinces Equis to use doubles you'll buy him a pony
and then drop him off in the programmer's offices.
Ken Hunt, does MetaStock use single precision for these calculations?
Kent
-----Original Message-----
From: Guy Tann <grt@xxxxxxxxxxxx>
To: Metastock User Group <metastock-list@xxxxxxxxxxxxx>
Date: Friday, August 25, 2000 1:29 AM
Subject: First calculation problem
List,
Well, I decided to do a little more work and discovered my first problem.
Somehow, MS came up with the following:
1486.20
- 1469.40
16.7999 instead of the more commonly expected 16.80
Now the first number is the Close and the second number is the day's low, so
we can't blame this on any previous calculation or anything left over from
something else. Well, that's not quite true. The Low used in the
calculation was the result of an IF() statement that made sure that the Low
was really the Low by our definition (by checking it against the previous
day's Close).
What internal methodology might cause this excellent bit of subtraction?
Granted, in checking out the 170-member dataset, I didn't check them all. I
checked the first 20 and the last 20. Now I'll probably have to go back and
sample some in the middle.
I used my trusty, solar powered calculator to double-check my Clipper output
and they both agree that MS is wrong. Any suggestions?
This is making me very nervous and might force me back to Excel and/or VB.
So far I've spent over two week on this relatively simple program and I have
to admit that I never thought it would be necessary to go back and
double-check such basic arithmetic.
Guy
Never be afraid to try something new. Remember, amateurs built the ark,
professionals built the Titanic.
|