Performs arbitrary precision math operations.


Result = SRP_Math(Operation, Value1, Value2, DecimalPlaces, ScientificNotation)


The mathematical result, or an error sting if there is an error.


OperationThe operation to perform on the values. Required.
Value1The first value to which the math operation is applied. Required for some operations.
Value2The second value to which the math operation is applied. Required for some operations.
DecimalPlacesThe number of decimal places to which the result will be rounded. Optional.
ScientificNotationDetermines the result's format. Optional.


Occasionally, the need arises to perform mathematical operations on decimal numbers with more than 16 digits. Currently, this is not possible in BASIC+ due to the 32-bit limit of modern PCs. SRP_Math breaks the 16 decimal place barrier by performing arbitrary precision math. In other words, SRP_Math will handle decimal numbers with any number of decimal places.


SRP_Math supports many operations, as listed below. This is the most important parameter since it determines how the values are to be treated. Some operations use both Value1 and Value2, some use only Value1, and a few even use no values at all. See the documentation on the individual operation for details. The operations are:

ABSOLUTEVALUEReturns the absolute value of a value.
ADDAdds two values.
ARCCOSCalculates the arc cosine of a value.
ARCCOSHCalculates the hyperbolic arc cosine of a value.
ARCSINCalculates the arc sine of a value.
ARCSINHCalculates the hyperbolic arc sine of a value.
ARCTANCalculates the arc tangent of a value.
ARCTAN2Calculates the two-argument arc tangent of two values.
ARCTANHCalculates the hyperbolic arc tangent of a value.
CEILINGRounds a value upward to the nearest integer.
COMPARECompares two values.
COSCalculates the cosine of a value.
COSHCalculates the hyperbolic cosine of a value.
CUBEROOTTakes the cube root of a value.
DECIMALDetermines whether a value is a decimal number or integer.
DIVIDEDivides two values.
EVENDetermines if a value is even.
EXPPerforms the exponential function of a value.
EXPONENTReturns the exponent component of a value.
FACTORIALComputes the factorial of a value.
FLOORRounds a value downward to the nearest integer.
GCDComputes the greatest common divisor of two values.
INTReturns the integer component of a value.
LCMComputes the least common multiple of two values.
LOGTakes the natural logarithm of a value.
LOG10Takes the common logarithm of a value.
MULTIPLYMultiplies two values.
NEGATENegates a value.
NONEReturns the value without performing any calculations.
ODDDetermines if a value is odd.
POWRaises a value to the power of another value.
RANDOMGenerates a random value.
ROUNDRounds a value to a given decimal place.
SIGDIGITSReturns the number of significant digits in a value.
SIGNReturns the sign of a value.
SINCalculates the sine of a value.
SINHCalculates the hyperbolic sine of a value.
SQUAREROOTTakes the square root of a value.
SUBTRACTSubtracts two values.
TANCalculates the tangent of a value.
TANHCalculates the hyperbolic tangent of a value.

Click on the operation above to read more details. Continue below for an explanation of the DecimalPlaces parameter.

Value1 and Value2

Value1 and Value2 can be any decimal number, but they must be encased in quotes. Furthermore, the values can be in fixed length decimal format or scientific notation; either way, SRP_Math will know what to do with them.

Note that Value1 and Value2 are not always used. See individual operation documentation for details.


The DecimalPlaces parameter identifies the number of decimal places to which the result should be rounded. If DecimalPlaces is greater than or equal to 0, then the value will be rounded to that number of digits and the result will be filled, with trailing zero's to fill out the decimal place specification. If DecimalPlaces is less than zero, all the significant digits of the result number will be output. If you omit this parameter, then -1 is used.

If result is 364.87451:

  • DecimalPlaces = 10: "364.8745100000"
  • DecimalPlaces = 1: "364.9"
  • DecimalPlaces = 0: "365"
  • DecimalPlaces = -1: "364.87451"


You can opt to have the result returned in scientific notation format by setting the ScientificNotation parameter to 1. When omitted, the default value is 0, and the result is formatted in fixed decimal format. The DecimalPlaces are still used to determine the number of decimal digits to display. Using the same example as above:

If result is 364.87451:

  • DecimalPlaces = 10: "3.6487451000E+2"
  • DecimalPlaces = 1: "3.6E+2"
  • DecimalPlaces = 0: "4E+2"
  • DecimalPlaces = -1: "3.6487451E+2"


It is possible for SRP_Math to generate errors. When an error occurs, it always in the format "ERROR: <message>". Therefore, you can check for errors using the following logic:

If Result[1, 5] EQ "ERROR" then 
   // process error here 

However, errors only occur when an operation is provided bad input. Here is a list of all the errors and the operations that generate them:

Error StringGenerated By
ERROR: Cannot divide by zero.DIVIDE
ERROR: Integer inputs required.GCDLCM
ERROR: Value must be >= 0.SQUAREROOT
ERROR: Value must be > 0.LOGLOG10
ERROR: Value1 and value2 cannot both be zero.ARCTAN2
ERROR: Value must be in range: 1 <= Value <= 1.ARCCOSARCSIN
ERROR: Value must be >= 1.ARCCOSH
ERROR: Value must be in range: 1 < Value < 1.ARCTANH
ERROR: Value cannot be a multiple of PI/2.TAN
ERROR: Unknown OperationOccurs for unrecognized operations

Some operations have limitations that are not fatal when not followed. These operations do not return errors, although the results may be undefined. For instance, EVEN and ODD require the use of integers, but an error is not returned when passing decimals. Instead, the operation is execute anyway and the results are considered undefined. See individual operation documentation for details.


Some developers will want to know about the performance cost of using SRP_Math. Simply put, SRP_Math is many times slower than BASIC+ arithmetic. Therefore, it is safe to say that you can have precision or you can have speed, but you cannot have both. In most cases, though, the performance cost is negligible. You can still perform thousands of calculations in a few hundred milliseconds.

For some hard numbers, execute the following stored procedure.

Compile subroutine SRP_Math_SpeedTest(VOID) 
   Name        : SRP_Math_SpeedTest 

   Description : The SRP_Math_SpeedTest subroutine compares the speed of SRP_Math to 
                 the speed of native BASIC+ arithmetic. 

 Declare function GetTickCount, SRP_Math 

 /*** The test is simple. Aggregate a decimal value, like PI, thousands of times ***/ 

// Testing Parameters 
CurrVal = 0 
Val = "3.14159" 
LoopCount = 100000 

// normal addition 
StartTime = GetTickCount() 
For i = 1 to LoopCount 
CurrVal += Val 
Next i 
NormalTime = (GetTickCount() - StartTime) 

// SRP_Math addition 
StartTime = GetTickCount() 
For i = 1 to LoopCount 
CurrVal = SRP_Math("ADD", CurrVal, Val) 
Next i 
SRPMathTime = (GetTickCount() - StartTime) 

// show the results 
Call Msg(@Window, "BASIC+ Time = ":NormalTime:" ms|SRP_Math Time = ":SRPMathTime:" ms") 


In my tests, SRP_Math took about 55 times longer to execute the entire loop. This ought to be an acceptable performance hit considering the advantages of arbitrary precision mathematics.


SRP_Math is a wrapper around the MAPM library written by Michael C. Ring.

  • No labels