Contents
A. Delphi/Kylix Math Unit  efg's Delphi Math Resources  
B. FloatingPoint Numbers, IEEE Math  efg's Delphi Math Functions  
C. Delphi Math Tips and Tricks  efg's Mathematics Page 
Question  Answer  
A1. Where is the Delphi Math unit?  The math unit is included in all versions of Delphi 4/5/6 and Kylix. The Delphi Math unit is available only with the Professional or Client/Server versions of Delphi 3  it is not available with the "Standard" version. It is also available with the Developer version of Delphi 2 and with the Client/Server versions of Delphi 1 or 2. You'll find the source code unit in directory ..\source\rtl\sys\math.pas.  
A2. What's new in the Delphi/Kylix Math unit? 


A3. What functions are in the Delphi 32 (i.e., Delphi 2  4)
Math unit? (Note: [n] indicates function was new in Delphi n) 
Min and Max constants for Single, Double,
Extended, Comp types Trig: ArcCos, ArcSin, ArcTan2, SinCos, Tan, CoTan, Hypot Angles: DegToRad, RadToDeg, GradToRad, RadToGrad, CycleToRad, RadToCycle Hyperbolic: Cosh, Sinh, Tanh, ArcCosh, ArcSinh, ArcTanh Logarithm: LnXP1, Log10, Log2, LogN Exponential: IntPower, Power Miscellaneous: Frexp, Ldexp, Ceil, Floor, Poly, EInvalidArgument type Statistical: Mean, Sum, SumInt [3], SumOfSquares, SumsAndSquares, MinValue, MinIntValue [3], Min overloads [4], MaxValue, MaxIntValue [3], Max overloads[4], StdDev, MeanAndStdDev, PopnStdDev, Variance, PopnVariance, TotalVariance, Norm, MomentSkewKurtosis, RandG Financial: TPaymentTIme type, DoubleDecliningBalance, FutureValue, InterestPayment, InterestRate, InternalRateOfReturn, NumberOfPeriods, NetPresentValue, Payment, PeriodPayment, PresentValue, SLNDepreciation, SYDDepreciation Note: Chapter 9, "The Shadowy Math Unit" in Kick Ass Delphi Programming 

A4. Where can I find other Delphi/ Pascal math function libraries?  Delphi Math Functions
Pages Source of Numerical Analysis Code in Pascal Jean Debord's TPMath page ESB Consultancy's ESBMaths Razor's Edge Software MathX SDL's (Software Development Lohninger) Math1 and Math2 
B. FloatingPoint Numbers, IEEE Math
Question  Answer  
B1. Overview Info  What Every Computer Scientist Should Know About
FloatingPoint Arithmetic http://docs.sun.com/source/8063568/ncg_goldberg.html 

B2. What are the Object Pascal numeric ordinal types? 
Notes:
Thanks to Roman Krejci for correcting an error in the above table about the generic integer in Delphi versions 23. (2 Aug 1998) 

B3. What are the floatingpoint data types? 
Notes:


B4. How can I learn more about floatingpoint numbers?  See Borland's Tech Info 1027, An Overview of Floating
Point Numbers, http://community.borland.com/article/0,1410,15855,00.html (The math in the article is OK, but the programming examples are in C, unfortunately.) The article "Reviewing Delphi by the numbers" in the April 1998 Delphi Developer's Journal (pp. 711) is a good overview of ordinal and floatingpoint types in Delphi. 

B5. What is IEEE floating point?  IEEE754 is a standard way to store floating point values on
a variety of computers. The Single, Double and Extended data types are all stored in IEEE
format. The older Real values are not stored in IEEE format.
See efg's NaN Tech Note IEEE Standard 754 Floating Point Numbers Formally Verifying IEEE Compliance of FloatingPoint Hardware A German description of IEEE754, Gleitkommazahlen nach IEEE, is available from http://www.informatik.unihalle.de/lehre/pascal/sprache/pas_ieee.html. Future 64bit Intel Architecture: IA64 FloatingPoint Operations and the IEEE Standard for Binary FloatingPoint
Arithmetic John Herbster's T_BinaryFloatingPoint program for analyzing the extended, double, and single binary point numbers. 

B6. How can I convert my old Real values to IEEE doubles?  See Richard Biffl's BPREAL.C function and related files: BPReal.ZIP To convert Turbo Pascal 3.0 BCD reals (10byte binary coded decimal reals with 18 significant digits) to Turbo Pascal 5.0 floating point numbers, download Turbo Pascal 5.5 from the Borland Community Museum: http://community.borland.com/museum, and install it. Look for BCD.PAS in the Turbo3 directory. 

B7. How can I convert between Microsoft Binary and IEEE format? Mac format? 
TI1431C, Converting between Microsoft Binary and IEEE format
Mark Di Val's Usenet Post
showing Microsoft's conversion functions (in C/C++) 

B8. What is a NAN? How can I test for one? What is an INF value? How can I do arithmetic with NAN and INF values?  In IEEE math a NAN is "not a number," i.e., an
undefined value. INF is infinity and can be positive or negative. Sample of easy way to define NAN and INF values: procedure TForm1.ButtonSpecialClick(Sender: TObject); CONST Infinity = 1.0/0.0; NaN = 0.0/0.0; begin // INF NAN ShowMessage(FloatToStr(Infinity) + ' ' + FloatToStr(NaN)) end; TI1716, Testing for Not a Number (NaN) Ray Lischner's math10.zip has some information about NANs and INFs but only compiles in Delphi 1. See IEEE754.TXT
for a short Delphi 3 unit that defines NAN, PositiveInfinity, etc. and
shows an example of how to use such values in expressions. (Also includes a DoubleToHex
function to display doubles in logical hex format.) 

B9. What is IEEE rounding?  efg's Set8087CW
and SetRoundMode rounding
example. See Set8087CW
for examples.
The default IEEE rounding rule is to round to the nearest even integer.
For example: 

B10. How can I round a floating point number in the traditional way: below 0.5 rounds down, 0.5 and above, rounds up?  FAQ1814D.txt Explanation (sic) of rounding http://community.borland.com/article/0,1410,16814,00.html See Set8087CW for how to control rounding modes. 

B11. When I do a StrToFloat('1234.5544') I get something like 1234.55440000000003. What is wrong here? 


B12. I'm trying to compare two floating point numbers that should be equal. Why aren't the two values equal? 
TI2139, How to Compare Floating Point Numbers Numerical Accuracy 101 for Delphi Developers Typically, you can use relative or absolute comparisons to avoid problems with "fuzz" (a term used with the language APL) with floatingpoint numbers. Because of this "fuzz" with floating point numbers, comparison of two
calculated floating point numbers should be based on either absolute or relative
error. IF ABS( (CalculatedValue  TrueValue) / TrueValue ) < AcceptableRelativeError THEN ... where AcceptableRelativeError
is application specific (and obviously TrueValue <> 0.0). HOWEVER, this form
of comparision can lead to dividebyzero problems. An alternative suggested in a
UseNet Post by
HansBernhard Broeker avoids this problem by using: The Delphi 3 math unit performs relative comparisons like this (but it's not exposed in the unit's interface): FUNCTION RelSmall(X, Y: Extended): Boolean;
Adam Majewski suggests this function to compute machine epsilon (10/7/2005): function calceps:real; {calceps.pas == This function returns the machine EPSILON or floating point tolerance, the smallest positive real number such that 1.0 + EPSILON > 1.0. EPSILON is needed to set various tolerances for different algorithms. While it could be entered as a constant, I prefer to calculate it, since users tend to move software between machines without paying attention to the computing environment. Note that more complete routines exist. Idan Nof 12 List. 1999 10:00 posts on comp.lang.pascal.borland } var 

B13. Explain how a comp type is a floating
point type but is a 64bit integer. (Note: Use the new Int64 type in Delphi 4 or later) 
Since the floating point unit (FPU) deals with this 64bit
integer, the comp type is treated as if it were a floating point type
even though it is a 64bit integer. Delphi's VCL defines a type called TLargeInteger
type that has a QuadPart comp type but also a LowPart and HighPart
that are LongInts. You can speed up conversion of a comp to an integer type using
TLargeInteger. See Borland's Assigning a comp type to an integer (FAQ 1965D). In D4 the TLargeInteger is an Int64, but through a pLargeInteger pointer the LowPart, HighPart and QuadPart of the Int64 can still be accessed like in D3. In D4 a TULargeInteger and a pULargeInteger are defined much like the TLargeInteger and pLargeInteger. The HighPart of a TULargeInteger is a DWORD (i.e., unsigned) while the HighPart of a TLargeInteger is a LongInt (i.e., signed). While not very intuitive, you must treat a comp type as a float when converting to a string. Specifically, you must use FloatToStr or FormatFloat to convert to a string. Consider the following example: VAR The resulting string, s, contains the following: 7FFFFFFFFFFFFFFF 2147483647 1 9.22337203685477581E18 Another example of using TLargeInteger is in Using the WIN API high resolution performance counter (FAQ 2028D). 

B14. How can I get Delphi to perform stronger type checking on user defined types?  For example, how can I define a type that descends from a double
but not pass this type to any function expecting a double (without a
warning)?
See Borland FAQ 2126D, "Getting stronger type checking" 

B15. Unsigned 32 Integers for Delphi 2/3  By Ray Lischner. The Unsigned unit implements unsigned 32bit integer arithmetic: comparisons, conversions, and division. Freeware. Source code and help file included. In Delphi 1.0, you must also download the FltMath unit, in math10.zip.  
B16. Floating Point Optimzation  Floating Point Optimization Guidelines www.optimalcode.com/float.htm 
C. Delphi Math Tips and Tricks
Topic  Tip or Trick 
C1. Integer to Float  Simple assignment: x := i; 
C2. Integer to String  s := IntToStr(i); or Format('%6.6d', [1234]) returns '001234' 
C3. Float to Integer  TRUNC(3.5) = 3 or ROUND (see "IEEE Rounding" above) 
C4. Float to String  Format, FormatFloat or FloatToStr, but also FloatToDecimal, FloatToStrF, FloatToText, FloatToTextFmt Examples: Format('%.3f times %d is %16s', [Measurement, Value, Key]); // "C" sprintf format specifications FormatFloat('##0.0', Factor); FloatToStr(x); 
C5. String To Float; Sting To Integer  If d is a double: d :=
StrToFloat('1234.5544'); If i is an integer: i := StrToInt('1234'); 
C6. How can I localize numbers to display correctly in both
the U.S. and European formats? What is the ThousandSeparator? What is the DecimalSeparator? 
VAR x: DOUBLE; i: INTEGER; BEGIN x := 1234567.8945; Button1.Caption := ThousandSeparator; ThousandSeparator := ','; DecimalSeparator := '.'; LabelUSA.Caption := FormatFloat('#,###,###.###', x); ThousandSeparator := '.'; DecimalSeparator := ','; LabelEuropean.Caption := FormatFloat('#,###,###.###', x); The resulting strings are (remember IEEE rounding rounds towards an even number): USA: 1,234,567.894 European: 1.234.567,894 Treat an integer the same way and use FormatFloat to get a ThousandSeparator in an integer string. 
C7. Dynamically allocated arrays (one dimension)  Arrays are incredibly useful and crop up in just about every
project we create. But “out of the box” they are rather inflexible as you need
to decide upfront how big your array should be. Not any more, Brian Long explains how to
make your arrays dynamic: resizeable and powerful, for Delphi 1 right through to Delphi 4,
with its new builtin dynamic arrays feature. Delphi Magazine, Issue 37, September 1998 How to Create an Array of 2,000,000 doubles in Delphi 1: Delphi1LargeArray.ZIP Also, see example below in "Open Array; Slice Function." Also look at Borland's Tech Info Report, Dynamically Allocating Arrays: Dr. Dobb's Journal on huge arrays in Turbo Pascal: ftp://garbo.uwasa.fi/pc/turbopas/ddj8803.zip Dr. Dobb's Journal on virtual arrays in Turbo Pascal: ftp://garbo.uwasa.fi/pc/turbopas/ddj8810.zip 
C8. 2D dynamic arrays  D5 Example using new ARRAY OF ARRAY construct
introduced in D4:
How to create a Bitmap from
numeric data? (D5) // Delphi 3 Example of 2Dimensional Dynamic Array 
C9. Open Array Parameters; Slice Function 
From the Delphi 3 Object Pascal Language Guide: Openarray
parameters allow arrays of varying sizes to be passed to the same procedure or
function. A formal parameter declared using the syntax: ARRAY OF T. Within the procedure
or function, the formal parameter behaves as if it was declared as ARRAY[0..N  1] OF T,
where N is the number of elements in the actual parameter. Note: When applied to
openarray parameters, the Low standard function returns zero, the High standard function
returns the index of the last element in the actual array parameter. The Slice function was introduced in Delphi 2. Use Slice for passing variablesized "open" arrays to certain functions, e.g., mean, sum, SumInt, MaxValue, MaxIntValue, etc. in Borland math unit, or userwritten routines. Simple Slice Example: CONST Example defining open array function, dynamic allocation of array, and Slice: // Calculate median intensity of RGB array The above RGBMedian function is called by the following: RowLast := BitmapIn.Scanline[j1]; An Open Array function called by the above example: FUNCTION MedianInteger (x: ARRAY OF INTEGER):
INTEGER; 
C10. Passing Multidimensional Arrays as Parameters  Borland's TI 1477D 
C11. How to use array of const  Borland TI 582D 
C12. Dynamic Arrays? A Class Wrapper for TList  Delphi Informant article, Feb. 1997, pp. 5865. 
C13. Linked Lists  When the Data is Too Dynamic for Arrays  Delphi Informant article, May 1998, pp. 6467.
Source code is www.informant.com/libs/delphi/3x/DI9805RS.ZIP 
C14. Dynamic array of TPoints to draw a polygon  See Borland's FAQ 919D 
C15. Initialization of twodimensional array  CONST A: ARRAY[1..2, 1..3] OF INTEGER = ( (1,2,3), (4,5,6)); Also see: Joselito G. Real UseNet Post about "Initializing ndimensional arraytype constants or static arrays" 
C16. Pointer Math  Subject: Re: Pointer Math From: Earl F. Glynn Date: Thursday, February 19, 1998 10:09 PM Newsgroups: borland.public.delphi.winapi ... In Delphi 2/3, if p is a pointer, you can always do something like this: p := Pointer(INTEGER(p) + 8); If p were a ^INTEGER before the above statement, it will point to "p+8" afterwards. For Delphi 1, see Borland's  TI 926D "How to do pointer arithmetic in Delphi"  TI 1542D, "A better way to do pointer arithmetic" 
C17. Numeric Edit Box  The NumEdit component is an edit box that only accepts valid numeric values either from the keyboard or through code. Download from Delphi Super Page: http://delphi.icm.edu.pl/ftp/d10free/numedit.zip 
C18. Numeric panel  JeanYves Quéinec's NumPanel demo program. Numpanel is a program sample (not a component) for "mouse only" numeric matrix input. It's very easy to use and simple to code. Two separate zip files contain the program (Numpanel.zip), and the text (Numpaneldoc.zip) in Html format with 3 images. 
Updated
05 Dec 2005
since
1 Nov 1998