$DOUBLE (ObjectScript)
Synopsis
$DOUBLE(num)
Parameter
Argument  Description 

num  The numeric value to be converted. You can also specify the strings “NAN” and “INF” (and their variants). 
Description
$DOUBLE returns a number converted to the IEEE doubleprecision (64bit) binary floatingpoint data type. This type of floatingpoint number can contain up to 20 digits. If num has more than 20 digits, $DOUBLE rounds the fractional portion to the appropriate number of digits. If the integer portion of num is more than 20 digits, $DOUBLE rounds the integer to 20 significant digits and represents the additional digits with zeros.
$DOUBLE converts a Caché floatingpoint number to an IEEE doubleprecision floatingpoint number. $DECIMAL performs the inverse operation, converting an IEEE doubleprecision floatingpoint number to a standard Caché floatingpoint number.
$DOUBLE generates floatingpoint numeric values that accord with the IEEE doubleprecision (64bit) binary floating point standard. It is primarily intended for interchange and compatibility with applications that use this data type standard. IEEE floatingpoint numbers are represented using binary notation. They have a precision of 53 binary bits, which corresponds to 15.95 decimal digits. (Note that the binary representation does not correspond exactly to a decimal fraction.)
IEEE floatingpoint numbers have greater min/max value range than standard Caché floatingpoint numbers. However, standard Caché floatingpoint numbers have a greater degree of precision. In most cases, standard Caché floatingpoint numbers are preferable.
A Caché numeric string literal that exceeds the min/max range supported by Caché floatingpoint data types (for example, “1E128”) is automatically converted to an IEEE doubleprecision floatingpoint number. This conversion is only performed on numeric literals; it is not performed on the results of mathematical operations. This automatic conversion can be controlled on a perprocess basis using the TruncateOverflow() method of the %SYSTEM.Process class. The systemwide default behavior can be established by setting the TruncateOverflow property of the Config.Miscellaneous class.
The num value can be specified as a number or a numeric string. It is resolved to canonical form (leading and trailing zeros removed, multiple plus and minus signs resolved, etc.) before $DOUBLE conversion. Specifying a nonnumeric string to num returns 0. Specifying a mixednumeric string (for example "7dwarves" or "7.5.4") to num truncates the input value at the first nonnumeric character then converts the numeric portion. A $DOUBLE numeric value supplied to a JSON array or JSON object follows different validation and conversion rules.
The Caché SQL data types DOUBLE and DOUBLE PRECISION represent IEEE floatingpoint numbers; the FLOAT data type represents standard Caché floatingpoint numbers.
Equality Comparisons and Mixed Arithmetic
Because numbers generated by $DOUBLE are converted to a binary representation that does not correspond exactly to decimal digits, equality comparisons between $DOUBLE values and standard Caché floatingpoint number values may yield unexpected results and should generally be avoided. Comparisons between $DOUBLE values and standard Caché floatingpoint number values are performed exactly, without rounding.
Mixed arithmetic operations involving a $DOUBLE value and one or more standard Caché numbers return a $DOUBLE value. In mixed arithmetic, Caché automatically converts all of the numbers to $DOUBLE values before performing the arithmetic operation. Caché handles conversions to/from $DOUBLE numeric representations and comparisons between numeric representations; these operations are, therefore, the same on all platforms. However, arithmetic operations involving $DOUBLE values are governed by the underlying operating system, and thus may occasionally differ between platforms. For further details on arithmetic operations involving IEEE double numbers, see the appendix “Numeric Computing in InterSystems Applications” in the Caché Programming Orientation Guide.
Integer Divide
With certain values, Caché decimal floatingpoint and IEEE double numbers yield a different integer divide product. For example:
WRITE !,"Divide operations:" WRITE !,"Cache /: ",4.1/.01 // 410 WRITE !,"Double /: ",$DOUBLE(4.1)/.01 // 410 WRITE !,"Integer divide operations:" WRITE !,"Cache \: ",4.1\.01 // 410 WRITE !,"Double \: ",$DOUBLE(4.1)\.01 // 409
Platform Independence
Standard Caché decimal floatingpoint numbers ($DECIMAL numbers) have an approximate precision of 18.96 decimal digits. This precision is consistent across all system platforms that Caché supports.
IEEE doubleprecision floatingpoint numbers ($DOUBLE numbers) have a standard internal representation that is platformindependent. Conversions and comparisons between $DOUBLE and $DECIMAL numbers are consistent across all system platforms that Caché supports. However, other computations on $DOUBLE numbers may show slight differences based on the system platform.
INF and NAN
Following the IEEE standard, $DOUBLE can return the strings INF (infinity) and NAN (not a number). INF can be positive or negative (INF and INF); NAN is always unsigned. While these are valid IEEE return values, they are not actual numbers.
INF and NAN as Input Values
One way to cause $DOUBLE to return INF and NAN is to specify the corresponding string as the num input value. These input strings are not casesensitive, and can take leading plus and minus signs (INF resolves signs, NAN ignores signs). To return NAN, specify “NAN”, “sNAN”, “+NAN”, “NAN”. To return INF, specify “INF”, “+INF”, “Infinity”. To return INF, specify “INF”, “+INF”.
IEEEError
IEEEError controls how $DOUBLE responds to a numeric conversion that cannot be resolved. If IEEEError is set to 0, $DOUBLE returns INF and NAN when it cannot resolve a conversion. If IEEEError is set to 1, $DOUBLE generates standard Caché error codes when it cannot resolve a conversion. The default is 1.
This behavior can be controlled on a perprocess basis using the IEEEError() method of the %SYSTEM.Process class. The systemwide default behavior can be established by setting the IEEEError property of the Config.Miscellaneous class.
Returning INF and NAN
$DOUBLE can return INF and NAN when you specify an extremely large number, or when you specify an unresolvable arithmetic operation. These values are only returned when IEEEError is set to return INF and NAN.
Extremely large floatingpoint numbers are not supported. The maximum supported value for a $DOUBLE binary floatingpoint number is 1.7976931348623158079e308. The minimum supported value for a $DOUBLE binary floatingpoint number is 1.0E323. A num value smaller than this returns 0.
The maximum supported value for a Caché decimal floatingpoint number is 9.223372036854775807e145. The minimum supported value for a Caché decimal floatingpoint number is either 2.2250738585072013831e308 (normal) or 4.9406564584124654417e324 (denormalized).
The following table shows the value returned or error generated by unresolvable arithmetic operations:
Input Value  IEEEError=0  IEEEError=1 

> 1.0E308  INF  <MAXNUMBER> 
< 1.0E323  0  0 
1/$DOUBLE(0)  INF  <DIVIDE> 
1/$DOUBLE(–0)  –INF  <DIVIDE> 
$DOUBLE(1)/0  INF  <DIVIDE> 
$DOUBLE(0)/0  NAN  <ILLEGAL VALUE> 
$ZLOG($DOUBLE(0))  –INF  <DIVIDE> 
Comparing INF and NAN
INF can be compared as if it were a numerical value. Thus INF = INF, INF '= –INF, –INF = –INF, and INF > –INF.
NAN cannot be compared as if it were a numerical value. Because NAN (Not A Number) cannot be meaningfully compared using numerical operators, Caché operations (such as equal to, less than, or greater than) that attempt to compare $DOUBLE(“NAN”) to another $DOUBLE(“NAN”) fail. Comparisons with NAN <= or >= are a special case, which is described in the appendix “Numeric Computing in InterSystems Applications” in the Caché Programming Orientation Guide.
$LISTSAME does consider a $DOUBLE(“NAN”) list element to be identical to another $DOUBLE(“NAN”) list element.
Caché does not distinguish between different NAN representations (NAN, sNAN, etc.). Caché considers all NANs to be the same, regardless of their binary representation.
$ISVALIDNUM, $INUMBER, and $FNUMBER
These ObjectScript functions provide support for $DOUBLE numbers.
$ISVALIDNUM supports INF and NAN. Although these strings are not numbers, $ISVALIDNUM returns 1 for these values, just as if they were numbers. When $DOUBLE is specified with a nonnumeric string, for example $DOUBLE(""), Caché returns a value of 0. For this reason, $ISVALIDNUM($DOUBLE("")) returns 1, because 0 is a number.
$INUMBER and $FNUMBER provide a “D” format option that supports $DOUBLE values. $INUMBER converts a numeric to a IEEE floatingpoint number. $FNUMBER “D” support includes case conversion of INF and NAN, and choosing whether $DOUBLE(0) should return 0 or 0.
INF and NAN with Operators
You can perform arithmetic and logical operations on INF and NAN. Use of operators with INF and NAN is not recommended; if such an operation is performed, the following are the results:
Arithmetic operators:
Addition  Subtraction  Multiplication  Division (/, \, or # operators) 
NAN+NAN=NAN  NANNAN=NAN  NAN*NAN=NAN  NAN/NAN=NAN 
NAN+INF=NAN  NANINF=NAN  NAN*INF=NAN  NAN/INF=NAN 
INFNAN=NAN  INF/NAN=NAN  
INF+INF=INF  INFINF=NAN  INF*INF=INF  INF/INF=NAN 
Logical operators:
Equality (=)  NAN  INF 
NAN  0  0 
INF  0  1 
Less Than (<) or Greater Than (>)  NAN  INF 
NAN  0  0 
INF  0  0 
Other operators, such as pattern matching and concatenation, treat NAN and INF as threecharacter alphabetic strings.
For further details on operations involving IEEE double numbers, see the appendix “Numeric Computing in InterSystems Applications” in the Caché Programming Orientation Guide.
INF and NAN Examples
$DOUBLE returns an INF value (or a INF for negative numbers) when the numeric value exceeds the available precision, as shown in the following example:
SET rtn=##class(%SYSTEM.Process).IEEEError(0) SET x=$DOUBLE(1.2e300) WRITE !,"Double: ",x WRITE !,"Is number? ",$ISVALIDNUM(x) SET y= $DOUBLE(x*x) WRITE !,"Double squared: ",y WRITE !,"Is number? ",$ISVALIDNUM(y)
$DOUBLE returns a NAN (not a number) value when the numeric value is invalid. For example, when an arithmetic expression involves two INF values, as shown in the following example. (An arithmetic expression involving a single INF value returns INF.)
SET rtn=##class(%SYSTEM.Process).IEEEError(0) SET x=$DOUBLE(1.2e500) WRITE !,"Double: ",x WRITE !,"Is number? ",$ISVALIDNUM(x) SET y= $DOUBLE(xx) WRITE !,"Double INF minus INF: ",y WRITE !,"Is number? ",$ISVALIDNUM(y)
JSON Numeric Literals
JSON validation of numeric literals is described in the SET command. $DOUBLE numeric literals specified in a JSON array or JSON object are subject to the following additional rules:

INF, INF, and NAN values can be stored in JSON structures, but cannot be returned by %ToJSON(). Attempting to do so results in an <ILLEGAL VALUE> error, as shown in the following example:
SET jary=[123,($DOUBLE("INF"))] // executes successfully WRITE jary.%ToJSON() // fails with <ILLEGAL VALUE> error

$DOUBLE(0) is stored in a JSON structure as 0.0. $DOUBLE(0) is stored in a JSON structure as 0. This is shown in the following example:
SET jary=[0,0,($DOUBLE(0)),($DOUBLE(0))] WRITE jary.%ToJSON() // returns [0,0,0,0.0]
Examples
The following example returns floatingpoint numbers of 20 digits:
WRITE !,$DOUBLE(999.12345678987654321) WRITE !,$DOUBLE(.99912345678987654321) WRITE !,$DOUBLE(999123456789.87654321)
The following example returns the value of pi as a $DOUBLE value and as a standard Caché numeric value. This example shows that equality operations should not be attempted between $DOUBLE and standard Caché numbers, and that the number of digits returned is greater for standard Caché numbers:
SET x=$ZPI SET y=$DOUBLE($ZPI) IF x=y { WRITE !,"Same" } ELSE { WRITE !,"Different" WRITE !,"standard: ",x WRITE !,"IEEE float: ",y }
The following examples show that a floatingpoint number is not necessarily equivalent to a numeric string of the same value:
SET x=123.4567891234560 SET y=123.4567891234567 IF x=$DOUBLE(x) { WRITE !,"Same" } ELSE { WRITE !,"Different" } IF y=$DOUBLE(y) { WRITE !,"Same" } ELSE { WRITE !,"Different" }
SET x=1234567891234560 SET y=1234567891234567 IF x=$DOUBLE(x) { WRITE !,"Same" } ELSE { WRITE !,"Different" } IF y=$DOUBLE(y) { WRITE !,"Same" } ELSE { WRITE !,"Different" }
See Also

ZZDUMP command

$DECIMAL function

$FNUMBER function

$NUMBER function

Data Types in Caché SQL Reference

Operators in Using Caché ObjectScript

Numeric Computing in InterSystems Applications in Caché Programming Orientation Guide