Microsoft KB Archive/46069

= Microsoft Knowledge Base =

Function to Round Floating Point to Specified Decimal Places
Last reviewed: January 12, 1995

Article ID: Q46069

The information in this article applies to:


 * Microsoft QuickBasic for MS-DOS, versions 1.0, 1.01, 2.0, 2.01, 3.0, 4.0, 4.0b, and 4.5
 * Microsoft Basic Compiler for MS-DOS and MS OS/2, versions 6.0 and 6.0b
 * Microsoft Basic Professional Development System (PDS) for MS-DOs and MS OS/2, versions 7.0 and 7.1
 * Microsoft QuickBasic for Apple Macintosh, version 1.0.

SUMMARY
There is no function built into Basic to round a floating-point variable to a specified number of decimal places and store the new value in a floating-point variable.

Below are two examples of functions that round the value stored in the variable through the use of integer rounding and reassignment to floating point. Note that the number of digits accepted by these functions is limited by the integer (or long integer) format.

Please also note that many floating-point decimal-notation numbers cannot be represented exactly in the binary format used for internal storage (IEEE or MBF, depending upon the Basic version), and you may notice a variation from the expected result at the limits of single or double precision. For example, where you expect 2.0, Basic might PRINT 1.9999999, even after using the rounding function code examples provided below.

The following numeric formats store numbers exactly: Decimal math packages (BCD), and CURRENCY, INTEGER, and LONG integer data types.

Alternative Methods for Rounding Floating-Point Variables
Note that Basic's PRINT USING statement rounds displayed values to any decimal place, but does not change the actual value stored in the variable. Also, the PRINT #n USING statement can output rounded values as ASCII strings to a disk file, but can't change the values stored in the floating-point variable.

For great accuracy in financial calculations (or other calculations that require a fixed number of decimal places), Microsoft recommends using the CURRENCY data type introduced in Basic PDS for MS-DOS, versions 7.0 and 7.1. The CURRENCY data type is very fast and gives decimal math accurate to 19 digits, with four digits to the right of the decimal point.

You may also use LONG integers (stored in number of cents) so that all calculations are performed using whole numbers. LONG integers are supported in QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.50; in Microsoft Basic Compiler for MS-DOS and MS OS/2, versions 6.0 and 6.0b; in Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2, versions 7.0 and 7.1 and in QuickBasic for Apple Macintosh, version 1.0. (Note that in the Macintosh versions of Basic and QuickBasic, Microsoft recommends using the decimal math (d) version rather than the binary math (b) version for the best accuracy for floating-point numbers.)

Another alternative is to store and manipulate floating-point numbers entirely as ASCII strings stored in string variables, but this is a low-speed alternative.

As another alternative, Basic PDS for MS-DOS, versions 7.0 and 7.1 introduce the add-on library FORMATx$ functions (FormatI$, FormatL$, FormatS$, FormatD$, FormatC$), which take a number and return a formatted string.

Code Example 1
The Round# FUNCTION below is designed for QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.5, Basic Compiler for MS-DOS and MS OS/2, versions 6.0 and 6.0b; and Basic PDS for MS-DOS and MS OS/2, versions 7.0 and 7.1 (You can convert this FUNCTION procedure to a SUBprogram procedure for use in QuickBasic for Macintosh, which doesn't support the FUNCTION statement but does support LONG integers.)

This FUNCTION rounds to the specified significant digits. For example, the program below rounds &quot;3.12345&quot; to 4 decimals as &quot;3.1235&quot;:

DECLARE FUNCTION Round# (x#, n%) PRINT Round#(3.12345#, 4) '  ' Round# rounds x# to n% decimal places. ' Single or Double can be passed. '  ' WARNING: This FUNCTION is limited by the shifted number '         x# * (10^n%)  <  2,147,483,647 (maximum LONG) '  FUNCTION Round# (x#, n%) temp& = x# * (10 ^ (n%))     ' Shift the number; store in LONG. Round# = temp& / (10 ^ (n%)) ' Shift number back. END FUNCTION

Code Example 2
A similar DEF FN function is as follows for other Basics that do not support LONG integers or FUNCTION procedures:

10 DEF FNRound(x!,n%) = (CINT(x! * (10^n%))) / (10^n%) 20 x! = 3.4567 30 n% = 3 40 PRINT FNRound(x!, n%) ' Prints 3.457. Warning: This function is limited by the following shifted number:

x! * (10^n%) < 32767 (maximum short integer) This DEF FN function can be used in the following products:


 * 1) Microsoft GW-Basic Interpreter for MS-DOS, versions 3.2, 3.22, and 3.23
 * 2) Microsoft QuickBasic for MS-DOS, versions 1.0, 1.01, 1.02, 2.0, 2.01, 3.0, 4.0, 4.0b, and 4.5
 * 3) Microsoft Basic Compiler for MS-DOS, versions 5.35 and 5.36
 * 4) Microsoft Basic Compiler for MS-DOS and MS OS/2, versions 6.0 and 6.0b
 * 5) Microsoft Basic PDS for MS-DOS and MS OS/2, versions 7.0 and 7.1
 * 6) Microsoft QuickBasic for Apple Macintosh, version 1.0
 * 7) Microsoft Basic Compiler for Apple Macintosh, version 1.0
 * 8) Microsoft Basic Interpreter for Apple Macintosh, versions 1.0, 1.01, 2.0, 2.1, and 3.0