Chapter 12 Caché Function Collection $DECIMAL Function

Article Directory

Chapter 12 Caché Function Collection $DECIMAL Function

Returns the number converted to a Caché floating point value.

Outline

$DECIMAL(num,digits)

parameter

  • num The numeric value to be converted. Usually, this is an IEEE floating point number.
  • digits Optional-an integer specifying the number of significant digits to be returned. $DECIMALThe IEEE floating-point rounding algorithm is used to round the return value to this number of digits. Valid values ​​are 1 to 38, and 0. If digits is greater than the number of digits, the value will remain unchanged. If digits is 0, num will not be rounded unless there are more than 20 significant digits.

description

$DECIMAL returns the floating-point number converted to the Caché decimal floating-point data type. This function is used to convert a decimal number in IEEE double-precision (64-bit) binary floating point format to a corresponding decimal number in Caché decimal floating point format. This is the opposite of what the $DOUBLEfunction performs.

CachéSQL data types DOUBLE and DOUBLE PRECISION represent IEEE floating-point numbers; FLOAT data types represent standard Caché decimals.

IEEE floating point numbers use 53 binary bits internally. Since most small decimal numbers don't have an exact binary representation, $DOUBLEthe decimal format is usually $DECIMALslightly different from the conversion. On all supported Caché system platforms, the accuracy of the standard Caché fractional part is approximately 18.96 decimal digits. When IEEE floating point numbers are displayed as decimals, the binary digits are usually converted to decimals with far more than 18 decimal digits. This does not mean that IEEE floating point numbers are more accurate than standard Caché decimals.

The num value can be specified as a number or a string of numbers. Before $DECIMALconversion, it will be parsed into canonical form (leading zeros and trailing zeros removed, multiple signs resolved, etc.). If the value exceeds num FLOAT data type can be converted to a value range, $DECIMALit generates <MAXNUMBER>an error. Specifying a non-numeric string for num will return 0. Specifying a mixed numeric string (such as “7dwarves”or “ 7.5.4”) for num truncates the input value of the first non-numeric character, and then converts the numeric part.

The default rounding is as follows:

  • Fractional part: If the number is not specified, and num having more than 19 significant digits, the $DECIMALfractional part is rounded, so that the resulting number of 19 digits (if followed by rounding to zero, compared to less). $DECIMALAlways round to the nearest decimal with the larger absolute value.
  • Very large integers: If the number is not specified, and to the left of the decimal point num more than 19 valid integer, $DECIMALare rounded, so that the resulting integer having 19 significant digits, and the remaining integer zero.
  • Very small fractional numbers less than 1: If digits are not specified, and num is the decimal point before the effective value, there are 19 decimals to the right of the decimal point, and there are more than 19 decimals on the right $DECIMAL, then zeros will be kept, and then rounded to the nearest whole number. . Decimals are rounded to 19 significant digits.
  • Integers with very small fractional numbers: If the number is not specified, and num is a number, the number contains a non-zero integer part. There are more than 19 zeros to the right of the decimal point before the effective value, which $DECIMALwill be rounded to an integer.

The digits parameter can be used to round the return value to a specified number of digits. The trailing zero is always removed. If the number is a positive integer, the IEEE rounding standard is used for rounding. If num significant digits (38 = and digital) over 38, then $DECIMALthe fractional part is rounded up to 38 digits, and that all subsequent figures num zero. If the number is greater than 38, an <ILLEGAL VALUE>error will be generated .

If digits is 0, the number is forced to be converted to string collation; otherwise, it is 0. Equivalent to ( + num)_“”. If num is less than 20 digits, then digits = 0 is the same as digits = 20.

However, if the number is 0 and num is greater than 20 numbers, special rounding (not IEEE rounding) is performed as shown below. Round off to return 20 digits. If the 20th digit is rounded to 0 or 5, the 20th digit is specially rounded. If the 20th place is rounded to 0 or 5, Caché rounds it to 9 or 4, respectively. If the 20th digit is rounded down to 0 or 5, Caché rounds it up to 1 or 6, respectively. The other 20 digital values ​​remain unchanged. The rounding algorithm is used to provide correct ordering rules for numbers and avoid inconsistencies in rounding.

Integer division

For some values, Caché decimal floating-point numbers and IEEE double-precision numbers will produce different integer division products. E.g:

DHC-APP>WRITE !,"Cache  \: ",$DECIMAL(4.1)\.01
 
Cache  \: 410
DHC-APP>WRITE !,"Double \: ",$DOUBLE(4.1)\.01
 
Double \: 409

INF given NAN

If num is INF, an <MAXNUMBER>error will be generated . If num is NAN, it will generate <ILLEGAL VALUE>an error. These invalid values ​​are shown in the following example:

DHC-APP>SET i=$DOUBLE("INF")
 
DHC-APP>SET n=$DOUBLE("NAN")
 
DHC-APP>WRITE $DECIMAL(i)
 
WRITE $DECIMAL(i)
^
<MAXNUMBER>
DHC-APP>WRITE $DECIMAL(n)
 
WRITE $DECIMAL(n)
^
<ILLEGAL VALUE>

Example

The following example shows that it $DECIMALis invalid when applied to decimals that have been in Caché format:

/// d ##class(PHA.TEST.Function).decimal()
ClassMethod decimal()
{
    
    
	SET x=$DECIMAL($ZPI)
	SET y=$ZPI
	IF x=y {
    
     
		WRITE !,"相同:"
		WRITE !,"Cache $DECIMAL: ",x
		WRITE !,"Native Cache:   ",y 
	} ELSE {
    
     
		WRITE !,"不同:"
		WRITE !,"Cache $DECIMAL: ",x
		WRITE !,"Native Cache:   ",y 
	}
}

The following example returns the value of pi as a $DOUBLEvalue and a standard Caché value. This example shows that $DOUBLEequality should not be attempted between standard Caché numbers, and that equivalence cannot $DECIMALbe restored by converting IEEE back to Caché using:

/// d ##class(PHA.TEST.Function).decimal1()
ClassMethod decimal1()
{
    
    
	SET x=$DECIMAL($ZPI)
	SET y=$DOUBLE($ZPI)
	SET z=$DECIMAL(y)
	IF x=y {
    
     
		WRITE !,"Cache & IEEE Same" 
	} ELSEIF x=z {
    
     
		WRITE !,"Cache & IEEE-to-Cache same" 
	} ELSE {
    
     
		WRITE !,"三者不同"
		WRITE !,"Cache decimal: ",x
		WRITE !,"IEEE float:    ",y
		WRITE !,"IEEE to Cache: ",z 
	}
}
DHC-APP>d ##class(PHA.TEST.Function).decimal1()
 
三者不同
Cache decimal: 3.141592653589793238
IEEE float:    3.1415926535897931159
IEEE to Cache: 3.141592653589793116

The following example $DECIMALreturns the conversion of pi to a $DOUBLEvalue. These conversions are rounded by different numeric parameter values:

/// d ##class(PHA.TEST.Function).decimal2()
ClassMethod decimal2()
{
    
    
	SET x=$DOUBLE($ZPI)
	WRITE !,$DECIMAL(x)
	/* returns 3.141592653589793116 (19 digits) */
	WRITE !,$DECIMAL(x,1)
	/* returns 3 */
	WRITE !,$DECIMAL(x,8)
	/* returns 3.1415927 (note rounding) */
	WRITE !,$DECIMAL(x,12)
	/* returns 3.14159265359 (note rounding) */
	WRITE !,$DECIMAL(x,18)
	/* returns 3.14159265358979312 */
	WRITE !,$DECIMAL(x,19)
	/* returns 3.141592653589793116 (19 digits) */
	WRITE !,$DECIMAL(x,20)
	/* returns 3.141592653589793116 (19 digits) */
	WRITE !,$DECIMAL(x,21)
	/* returns 3.141592653589793116 (19 digits) */
	WRITE !,$DECIMAL(x,0)
	/* returns 3.1415926535897931159 (20 digits) */
}

DHC-APP>d ##class(PHA.TEST.Function).decimal2()
 
3.141592653589793116
3
3.1415927
3.14159265359
3.14159265358979312
3.141592653589793116
3.141592653589793116
3.141592653589793116
3.1415926535897931159

Guess you like

Origin blog.csdn.net/yaoxin521123/article/details/108355040