Get this... 02.144179 equals 02.144180 (OpenInsight 32-bit Specific)
At 21 APR 2003 11:18:01AM Richard Hunt wrote:
While testing some of my software I found that 02.144179 equals 02.144180
In my freight billing module, it seperates the origin terminal code from the invoice with a ".". This is a carryover from my UniVerse software. Didn't think much of it really since string variables are considered strings and not numbers. Or well that is the case in UniVerse and not the case in OpenInsight and Arev.
When doing a "READ" or "XLATE" all is ok. Both items are read just fine. When doing an "IF / THEN", it fails.
ITEM=02.144180"
LAST_ITEM=02.144179"
IF ITEM NE LAST_ITEM THEN
GOSUB DISPLAY_INFO
END
The "THEN" part of the "IF / THEN" is not executed.
I remember this to be a bug in the mid 1980's within Prime Information. They fixed it by leaving string variables as strings. They also had a "PRECISION" statement that would allow the user to control the number of decimal places when the system converts a numeric value to a character string.
I have noticed that Arev and OI have the "@PRECISION" system variable, and it seems to do nothing.
This causes a mini disaster when converting from UniVerse to OpenInsight.
At 21 APR 2003 12:28PM Warren wrote:
What happens if you append an alpha character (e.g. ITEM=A":ITEM, OLD_ITEM=A":ITEM) before the compare?
At 21 APR 2003 01:01PM Richard Hunt wrote:
Warren,
Prefixing or suffixing an alpha character would cause it to work properly. Although I was hoping for a more "professional" resolve. Or should I ask if there will be a fix to this.
All I have to do now is to look thru 139 programs and 58,478 lines of code to check for this glitch. And that is just the Freight Billing Module.
This almost reminds me of the math coprocessor glitch that was found many years ago (I think it was Intel) and they said too bad.
At 21 APR 2003 01:36PM Matt Sorrell wrote:
Richard,
Be careful when you are adding an alpha character. Pretty much any character except 'E' will work. The 'E' is used in scientific notation, and will also cause false positive matches.
I remember when I first ran across this. It took me quite a while, as I recall, to figure out exactly why my inventory module was "freaking" out. I finally tracked it down to part numbers that contained an 'E' in the middle of the number, where the rest of the part number was numeric. Lots of fun to fix, let me tell you.
msorrel@greyhound.com
At 21 APR 2003 02:46PM Don Miller - C3 Inc. wrote:
This problem has been around since the year dot. It caused me problems at one of my customers (a chemical company that used our bill-of-materials processor for formula books). They suffixed their numeric component numbers with a .nnnnnn for revision numbers. There was a change between REV-G, AREV 1.x and AREV 2.x. And, yes, there wasn't an elegant solution .. just a brute force approach:
FUNCTION MATCH_NUMS(VAL1,VAL2)
* returns 0 if equal
* 1 if Val1 is greater
* 2 if Val2 is greater
* leave out the error checking ..
RET=0 ;* default
* get around the bogus equality test
IF VAL1:'z'=VAL2:'z' then RETURN RET
* now see which is greater
IF VAL1 ] VAN2 THEN RETURN 1
RETURN 2
Don M.
At 21 APR 2003 03:48PM Victor Engel wrote:
You may wish to look into the extended precision operators. The names of the operators are basically _##X, where ## is the name of the operator you are used to. So the extended precision operator corresponding to NE is _NEX.
At 21 APR 2003 04:16PM [url=http://www.sprezzatura.com" onMouseOver=window.status= Click here to visit our web site?';return(true)]The Sprezzatura Group[/url] wrote:
We checked this when we noticed your post on this matter from a few years ago
but these operators never made it into OI.
World Leaders in all things RevSoft
At 21 APR 2003 04:49PM Victor Engel wrote:
I was wondering about that. Thanks for following up.
In any case, doing comparisons like this with floating point numbers is inherently dangerous, especially when converting between bases. On screen, and in programs and data interfaces, we are likely to use base 10, because that's what looks good and familiar to us. With a few exceptions (TI/99, for example) computations are done in a base that is a power of 2. While it is possible to convert real numbers between base 2 and base 10, it is not always possible with floating point numbers. This is because floating point numbers are not infinite, so the floating point version of the number is really just an approximation.
At 21 APR 2003 05:50PM [url=http://www.sprezzatura.com" onMouseOver=window.status= Click here to visit our web site?';return(true)]The Sprezzatura Group[/url] wrote:
Regretfully this is one of the only serious drawbacks of a non data typed environment, and if the price we have to pay for that is a NUMTOCHAR conversion then so be it.
World Leaders in all things RevSoft
At 21 APR 2003 07:37PM Warren wrote:
Use a different delimiter than a '.'
Then write a user ICONV/OCONV to change that delimiter to a '.' for output.
At 21 APR 2003 10:33PM Richard Hunt wrote:
Warren,
Actually I am going about almost the opposite. See the "." was used because it is on the numeric keypad (data entry easy). So I will be using an ICONV method.
At 21 APR 2003 10:49PM Richard Hunt wrote:
Ya know guys…
I would not be so ticked off if it wasn't for the fact that UniVerse does not have this problem.
Although I will avoid this problem in the future. My fix is to seperate the origin terminal code "02" from the invoice "14179" and use a "-" delimiter rather than a ".".
I never noticed it before… that is exactly what Watkins Motor Lines, Motor Cargo, and Yellow Freight does. Just to name a few.
At 22 APR 2003 07:42AM Don Miller - C3 Inc. wrote:
Richard ..
Just a funny historical note. When I was writing the Pick OS implementation for Microdata Reality systems, it was common to use a decimal point in keys to indicate multi-part keys (Account#.SubAcct#.CostCenter) in G/L for example. The very same problem with numeric interpretation of keys occured there if there was no CostCenter. It was viewed as a floating-point value during equality testing. We worked around it then by forcing a kind of data-typing algorithm that generally worked. The issue was that if an actual decimal point was stored in the data, then we treated it as a string no matter what. True numeric values were stored without decimal points so that binary arithmetic was applied .. more or less successfully. Still, there is always problem in converting floating point numbers from base-2 to anything else.
Universe, as you correctly observe, got around this problem. I don't think you'll see any correcton of this issue in RTI because there are just too many applications out there which have gotten around it (NUM2CHAR conversion, for example).
Don M.
At 22 APR 2003 12:35PM Victor Engel wrote:
A discussion of the issue can be found in the Arev knowledge base available on this site:
The system of real numbers you use for pencil and paper calculations is conceptually infinite and continuous. There are no upper or lower limits to the magnitude of the numbers you can employ in a calculation, or to the precision (number of significant digits) you can represent. For any real number, there are always an infinity of numbers both larger and smaller. There is also an infinity of numbers between (i.e., with more significant digits than) any two real numbers. For example, between 2.5 and 2.6 are 2.51, 2.501, 2.5001 2.50001, and 2.59, 2.599, 2.5999, 2.59999, etc. Ideally, a computer would be able to operate on the entire real number system. In practice this is not possible. Computers, no matter how large, ultimately have fixed size registers and memories that limit the system of numbers that can be accommodated. These limitations proscribe both the range and the precision of numbers. The result is a set of numbers that is very large but finite and discrete, rather than infinite and continuous. This computerized sequence is a subset of the real numbers, which is designed to form a useful approximation of the real number system. A Simple Example This approximation is readily demonstrated in our everyday life using the following simple examples of decimal arithmetic with the values two-thirds and one-third. Truncation Rounding Addition 0.6666 0.6667 +0.3333 +0.3333 -------- ------- 0.9999 1.0000 Subtraction 0.6666 0.6667 -0.3333 -0.3333 -------- -------- 0.3333 0.3334 Notice that the accuracy of the results depends on two factors: the presence or absence of rounding when approximating a value (two-thirds in our example), and the operation being performed (addition, subtraction, etc.). The Binary Situation The same situation occurs in binary arithmetic used in computers. As with the example above, there are certain numbers which can not be precisely represented and require that a choice be made as to how they will be approximated. Of critical interest in this situation is the fact that a fraction which does not require approximation in decimal generally requires approximation in binary. For example, the decimal value 0.1 converts to the non-terminating binary value 0.00011001100110011 .... This requires that a rounded or truncated approximation be used when storing it in memory. Computer Implementations Whenever approximations are required in a computer, a special form of data representation and calculation is used. This special form is referred to as Floating Point. Floating Point allows a great many, but not all, of a large range of real numbers to be represented, and is analogous to the scientific notation you may have seen on calculators and in physics or chemistry textbooks. Rather than exactly representing a number as its complete string of digits, however many, Floating Point breaks a number into two parts: an exponent (sometimes called a characteristic), and its most significant digits (sometimes called either a mantissa or a significand). Floating Point primarily differs from scientific notation only in its use of binary digits (rather than decimal ones) and its need to comply with each computer's fixed size registers and memories. This restricts the number of digits which can be used. IBM Personal Computers In the case of IBM PC's, the maximum precision form of Floating Point uses a total of 80 binary digits (bits) to represent numbers. Sixteen of these are used for the exponent and 64 for the significand. This provides PC users with a range of representable numbers from +-3.4 x 10^4932 to +-1.2 x 10^4932 with a precision of about nineteen decimal digits. Advanced Revelation's Use of Floating Point All PC versions of Advanced Revelation use and store 80 bit Floating Point numbers whenever any of the following conditions are satisfied: * A Numeric Processor Extension (i.e., a mathematics co-processor such as an 8087, 80x87) is available in the PC hardware. * An integer constant greater than +-32,767 is compiled by R/BASIC. * A number with a fractional value (e.g., 39.95) is used. * Addition, subtraction or multiplication uses or generates a result greater than a 32 bit integer (less than -2 x 10^9 or greater than +2 x 10^9). * Whenever division is performed. Advanced Revelation's Accommodations to Floating Point Since its inception, Advanced Revelation has, under certain circumstances, implicitly adjusted final arithmetic results in an attempt to compensate for any Floating Point approximation-induced discrepancies. The types and magnitudes of these adjustments has varied with different versions: Revelation and Advanced Revelation 1.X * Number-to-string conversions rounded, and displayed in Fixed Point format as a maximum of 14 whole-number digits plus a maximum of 4 fractional digits. * Equal and Not-Equal comparison tests performed to a maximum of 4 rounded fractional digits (i.e., to the nearest one ten-thousandth). * Other comparison tests performed on the entire number. Advanced Revelation 2.0 * Number-to-string conversions used as stored in memory, and displayed in either Fixed Point or Floating Point format with any number of whole and fractional digits to a total of 18. * Equal and Not-Equal comparison tests performed to a maximum of 4 rounded fractional digits (i.e., to the nearest one ten-thousandth). * Other comparison tests performed on the entire number. Advanced Revelation 2.1 * Number-to-string conversions rounded, and displayed in either Fixed Point or Floating Point format with any number of whole and fractional digits to a total of 15. * Equal and Not-Equal comparison tests performed to a maximum of 4 rounded fractional digits (i.e., to the nearest one ten-thousandth). * Other comparison tests performed on the entire number. Unfortunately, depending on the actual values used and the operations performed, even these implicit adjustments can leave results which are not precisely accurate. The worst cases of this most frequently occur during subtraction of numbers close in value (e.g., 30,000.01 - 30,000.00). As the mathematicians always state, no matter how hard you try, there will always be some numbers that will not behave correctly for any given set of values, operations, and rounding choices. See again the Simple Example of decimal arithmetic earlier in this bulletin. Notice that no matter whether truncation or rounding is chosen, either addition or subtraction, but not both, will give a result requiring adjustment. Even if an appropriate compensating algorithm for calculations based on thirds is defined, you can always change the example to be based on sixths, ninths, fifteenths, ninety-ninths, etc. in such a way that the thirds-based algorithm will fail. The General Theory that there are an infinity of numbers between any two real numbers also means that there are an infinity of compensating algorithms. Since Advanced Revelation has no knowledge of the dynamic operation sequences or values being processed by any application program, it is impossible to implement a single implicit compensating algorithm that will work for every situation. Explicit Control of Floating Point using Advanced Revelation Advanced Revelation does provide an explicit method for application programs to compensate for approximation-induced discrepancies: ICONV and OCONV, Masked Decimal. These functions can be invoked to, among other things, convert results to a specified number of fractional digits, with or without rounding. For example, consider the R/BASIC program VAL_A=30000.01 VAL_B=30000.00 RESULT_IMP=VAL_A - VAL_B REV_INTERNAL=ICONV(RESULT_IMP, "MD2") RESULT_EXP=OCONV(REV_INTERNAL, "MD2") PRINT RESULT_IMP PRINT RESULT_EXP whose Advanced Revelation 2.1 implicitly compensated, and explicitly compensated results are 9.99999999999979E-3 .01 For reference, the uncompensated result is 0.00999999999999978684, which is what would have been displayed using the non-adjusting Advanced Revelation 2.0. The more restrictive Revelation and Advanced Revelation 1.X would have displayed .01, but would have suffered a loss of precision had the result required more than four fractional digits. Future Directions in Advanced Revelation Revelation Technologies is analyzing several areas for potential changes to Advanced Revelation's present computational processes. Among these are: * The criteria under which Floating Point is selected for calculations rather than integer. * User-specifiable implicit rounding or truncation precision for number-to-string conversions. * The number of fractional digits tested by Equal and Not-Equal comparisons, and whether they should first be rounded or not. * Use of strength reductions in special situations (e.g., performing multiplications for exponentiation to small integer powers rather than using logarithms). Intertwined issues being considered when analyzing these areas include: * Backward compatibility for existing 2.X applications (i.e., any changes should not impact the functioning of current programs), * The possible impact of developer control of the implicit compensating algorithm - particularly in the cases of different algorithms being used on different machines in a network environment, and for Environmental BondingTM, * The accuracy of and potential overflow/underflow of computations where Floating Point may no longer be employed. * The definitions of Equal and Not-Equal in an approximating environment. * Program execution speeds of various processor configurations with and without Numeric Processor Extensions.
At 22 APR 2003 01:09PM Don Miller - C3 Inc. wrote:
Victor .. a long time ago, I copied and saved this document. I think there was an even more exacting one years ago on the Compuserve site (I'm not sure who the author was .. senior moment). I suppose I can go hunt it down, though. There is an interesting set of observations about this issue in Knuth's Fundamental Algorithm's book as well.
Don M.
At 22 APR 2003 01:26PM Richard Hunt wrote:
Thanks everyone. It really helps alot to get so much info from you all. Now that I am clear on this subject, I will avoid any future problems.
I have picked to replace the "." with a "-". That way the invoice number will be reconized as a character string rather than a decimal number. I have tested it and it resolves the problem.
Kinda funny how one little thing can set me back by oh 2 weeks. Well better that I caught it while testing the software rather than a "live" customer catching it.
At 22 APR 2003 03:15PM Victor Engel wrote:
There was another document provided in the release notes with Arev 2.1 I think, or whatever version it was that introduced the extended precision operators.