|
Home|Management Portal|Index
|
Technical Articles
InterSystems Product Miscellany
« »
|
|
|
| Server:docs.intersystems.com |
| Instance:CACHE20081 |
|
User:UnknownUser |
|
|
Introduction
Any attempt to systematically catalog and explain a complex product or set of products invariably ends up with a collection of facts and figures that do not fit easily into the proposed organization. This document attempts to collect these minor but important items into one place so that they will not be lost or go unrecorded.
In Caché, the current date and time is contained in a special system variable, $H (for "HOROLOG"). The format is a pair of numbers separated by a comma, e.g. "54321,12345.789" The first number, an integer, is the number of days since December 31st, 1840; that is day number 1 is January 1st, 1841. The second is the number of seconds, and possibly fractions of a second, since midnight on that day.
In the Just Ask! column of the September 1993 issue of M Computing, a publication of the M Technology Association, Silver Spring, MD 20903, James M. Poitras wrote:
"Starting in early 1969, our group created the Chemistry Lab
application at Massachusetts General Hospital (MGH), which was
the first package in the MGH MUMPS with Global Data Storage and
many of the features of the language today..."
"When we started programming, there were no utility programs of
any type. We had to write them all: time, date, verify database,
global tally, print routine, etc. I ended up writing initial
versions of most of these.
"When I decided on specifications for the date routine, I
remembered reading of the oldest (one of the oldest?)
U.S. citizen, a Civil War veteran, who was 121 years old at the
time. Since I wanted to be able to represent dates in a
Julian-type form so that age could be easily calculated and to be
able to represent any birth date in the numeric range selected, I
decided that a starting date in the early 1840s would be 'safe'.
Since my algorithm worked most logically when every fourth year
was a leap year, the first year was taken as 1841. The zero point
was then December 30, 1840...
"That's the origin of December 31, 1840 or January 1, 1841. I
wasn't party to the MDC (M Development Committee) negotiations,
but I did explain the logic of my choice to members of the
Committee."
Caché supports two different ways of representing numbers. The first of these, native format, has its roots in the original implementation of
MUMPS. The second, more recent format adheres to the
IEEE-754 standard. This latter format is referred to as $DOUBLE format after the
Objectscript function that is used to convert numbers into this form.
Caché represents numbers internally in two parts. The first is called the mantissa or significand. It contains the significant digits of the number. The significand can be thought of as an integer. The second is the exponent. The product of the significand and 10 raised to the power of the exponent is the actual value of the number.
The significand is stored internally as a signed 64bit integer. Assuming an exponent of zero, this means that the largest positive integer that can be represented without loss of precision is 9,223,372,036,854,775,807; the largest negative integer is -9,223,372,036,854,775,808.
The exponent is represented internally as a signed byte and ranges from 127 to -128.
Thus, the range of numbers that can be represented in Cache' native format approximately covers the range 9.22E145 to 1.0E-128. Most numbers in this range can actually be represented with a precision of 19 digits. Those numbers with a significand greater than 9,223,372,036,854,775,807 (or less than -9,223,372,036,854,775,808) cannot.
The Caché $DOUBLE format conforms to IEEE 754: Standard for Binary Floating-Point Arithmetic, specifically, the 64-bit binary (double-precision) representation. This means it consists of three parts:
-
-
an 11bit power of two exponent (The exponent value is biased by 1023, so the internal value of the exponent for the number 1 is 1023 rather than 0.)
-
a positive 52bit integer significand (Since the significand is always treated as a positive value and normalized, the leading 1-bit is assumed and the significand is numerically 53 bits long.)
The largest integer (with exponent 0) that can be represented exactly is 9,007,199,254,740,992.
This representation has two additional features that are not available with Caché native format:
-
the ability to represent the results of invalid computations, such as taking the square root of a negative number, as a NaN (Not any Number)
-
the ability to represent infinity, for example, as the result of attempting to compute the logarithm of zero
For further details, please refer to the standard and its references to other explanatory documentation.
The choice of which format to use is largely determined by the requirements of the computation. Caché native format permits 18 decimal digits of accuracy while $DOUBLE guarantees only 15.
In most cases, Caché native format is simpler to use and provides more precise results. It is usually preferred for computations involving decimal values (such as currency calculations) because it gives the expected results. Decimal fractions cannot often be represented exactly as binary fractions.
On the other hand, the range of numbers in $DOUBLE is significantly larger than in native format: 1.0E308 versus 1.0E145. Those applications where the range is a significant factor should use $DOUBLE.
Also, those applications that will share data externally may also consider maintaining data in this format because it will not be subject to implicit conversion. Most other systems use the IEEE standard as their representation of binary floating-point numbers because it is supported directly by the underlaying hardware architecture. So values in Caché native format must be converted before they can be exchanged, for example, via ODBC/JDBC, SQL, or language binding interfaces.
Automatic Coercion Of Numerics
In general, computations involving Caché native format values will result in a Caché native result. Any computation cinvolving a $DOUBLE value will produce a result in $DOUBLE format.
In Caché 2007.2, numbers are automatically converted to a $DOUBLE representation when the result of a computation exceeds the range of a native number.
Caution:
This automatic conversion may change in the future because it results in a silent loss of precision. InterSystems recommends that conversions between Caché native format and $DOUBLE be explicitly controlled by the application.
Numeric Values Of Strings
In Caché, if a string is used in an expression, the value of the string is the value of the longest numeric literal contained in the string starting at the first character. If there is no such literal present, the computed value of the string is zero.
According to the
M Standard (ANSI/MDC X11.11994), 7.1.4.3
Numeric data values, numbers must not contain leading zeroes (after the sign if there is one), or trailing zeroes at the end of decimal fractions. Those numeric values that do not adhere to these rules are treated as if they were strings. Because they have a numeric value that can be determined, they can be used in computations. However, when they are used (for example) as subscripts for local or global variables, they are treated as strings and collate as strings. Thus, in the list of pairs:
those on the left are treated as numbers and those on the right are treated as strings. For example,
SET ^||TEST("1") = "standard"
SET ^||TEST("02") = "not standard"
SET NF = "Not Found"
WRITE """1""", ": ", $GET(^||TEST("1"),NF), !
WRITE 1, ": ", $GET(^||TEST(1),NF), !
WRITE """02""", ": ", $GET(^||TEST("02"),NF), !
WRITE 2, ": ", $GET(^||TEST(2),NF), !
WRITE !
SET SUBS=$ORDER(^||TEST(""))
WRITE "Subscript Order:", !
WHILE (SUBS '= "") {
WRITE SUBS, !
SET SUBS=$ORDER(^||TEST(SUBS))
}
These are arguments which can be used to control the import of external sources into Caché, compile existing applications, and export these to external destinations. In the class documentation for
%SYSTEM.OBJ, these are often supplied as the value of the parameter,
qspec. The available settings for each can be displayed by the commands:
Do $SYSTEM.OBJ.ShowFlags()
Do $SYSTEM.OBJ.ShowQualifiers()
Of the two, the flags are the earlier. They were modeled on UNIX command-line parameters and thus are one- or two-character sequences. The existing flags and their meanings are:
Existing Flags
| Flag |
Meaning |
Default |
| a |
Include application classes. |
X |
| b |
Include subclasses. |
|
| c |
Compile. Use this flag while loading a CDL file will cause the classes loaded to be compiled as well. |
|
| d |
Display. |
X |
| e |
Delete extent. |
|
| f |
Force. Force a compilation even when classes instances are in use. Existing objects are invalid after compilation. |
|
| g |
Skip XML export of selectivity and extent size in class storage. |
|
| h |
Generate help. |
|
| i |
Validate XML export format against schema on Load. |
X |
| k |
Keep source. When this flag is set, source code of generated routines will be kept. |
|
| l |
Use lock while compilation classes. |
X |
| p |
Include percent classes. |
|
| q |
SQL-only compilation. (deprecated) |
|
| r |
Recursive. It means include all the classes that are dependency predecessors. |
|
| s |
Include system classes. |
|
| u |
Update only. It means do not compile classes that are up-to-date. |
|
| v |
Keep valid. When combined with "f" flag (which forces recompilation), also keeps the objects valid after compilation finishes. |
|
| y |
Include classes that are related to the current class in the way that they either reference to or are referenced by the current class in SQL usage. |
|
| o1 |
Optimize ..Property to i%Property where possible. |
X |
| o2 |
Optimize calls within this class, no incremental compile support. |
|
| o3 |
Optimize calls within this class and to system classes. |
|
| o4 |
Optimize calls to all classes (only works from CompileAll entry point). |
|
Note:
Flags may be turned off by preceding them with a dash (-), so the specification
c-o1 indicates a compilation without any optimization.
During the development of Caché version 5.1, it became clear that flags would be insufficient to provide for the emerging needs of import, export and compilation. Rather than replace the flags mechanism, a newer, more extensible set of controls was implemented: qualifiers. To preserve backward compatibility, the flag mechanism remains fully supported. In addition, a qualifier exists whose meaning is the same as each existing flag, and the two may be used in the same specifier.
Since there are so many more qualifiers, they are organized into groups according to the function they control as shown in the following tables:
Compiler Qualifiers
| Flag |
Meaning |
Default |
| /application |
Include application classes. |
1 |
| /autoinclude |
Automatically include any classes that are not up to date required to compile this class |
1 |
| /checkschema |
Validate imported XML files against the schema definition. |
1 |
| /checksysutd |
Check system classes for up-to-dateness |
0 |
| /compile |
Causes classes loaded to be compiled as well. |
0 |
| /cspcompileclass |
Causes classes created by CSP or CSR load to be compiled. |
1 |
| /csphidden |
Classes generated from CSP and CSR compilation are marked as hidden. |
1 |
| /deleteextent |
Delete extent. |
0 |
| /diffexport |
Do not include any time or platform information in export so the files can be run through diff/merge tools. |
0 |
| /displayerror |
Display error information. |
1 |
| /displaylog |
Display log information |
1 |
| /foldmethods |
Do not generate two methods with identical contents. |
0 |
| /force |
Force a compilation even when classes are in use. |
0 |
| /generatemap |
Generate the map file. |
1 |
| /importselectivity |
Import the selectivity values stored in the storage defintiion when importing XML file |
1 |
| /includesubpackages |
Include sub-packages. |
1 |
| /incremental |
Allow incremental compilation. |
0 |
| /keeporefvalid |
When combined with /force, keeps the in-memory objects valid. |
0 |
| /keepsource |
Keep the source code of generated routines. |
0 |
| /lock |
Use LOCK command while compilation classes. |
1 |
| /mapped |
Include classes mapped from another database |
0 |
| /percent |
Include percent classes. |
0 |
| /predecessorclasses |
Recursively include dependency predecessor classes. |
0 |
| /relatedclasses |
Recursively include related classes. |
0 |
| /sqlonly |
SQL-only compilation. (deprecated) |
0 |
| /subclasses |
Recursively include sub-classes. |
0 |
| /system |
Include system classes. |
0 |
Export Qualifiers
| Flag |
Meaning |
Default |
| /application |
Include application classes. |
1 |
| /checksysutd |
Check system classes for up-to-dateness |
0 |
| /checkuptodate |
Do not export the class storage information. |
1 |
| /createdirs |
Create directories if they do not exist |
0 |
| /diffexport |
Do not include any time or platform information in export so the files can be run through diff/merge tools. |
0 |
| /displayerror |
Display error information. |
1 |
| /displaylog |
Display log information. |
1 |
| /exportselectivity |
Export the selectivity values stored in the storage defintiion for this class |
0 |
| /importselectivity |
Export the selectivity values stored in the storage defintiion for this class |
1 |
| /includesubpackages |
Include sub-packages. |
1 |
| /javadoc |
Do not create javadoc. |
1 |
| /make |
Only generate dependency or class if timestamp of last compilation is greater than timestamp of last generation |
0 |
| /mapped |
Include classes mapped from another database |
0 |
| /newcollections |
Use native Java collections. |
1 |
| /percent |
Include percent classes. |
0 |
| /pojo |
POJO generation mode |
0 |
| /predecessorclasses |
Recursively include dependency predecessor classes. |
0 |
| /primitivedatatypes |
Use Java primitives for %Integer, %Boolean, %BigInt, %Float . |
0 |
| /projectabstractstream |
Project classes that contain methods whose arguments are abstract streams or whose return type is an abstract stream. |
0 |
| /projectbyrefmethodstopojo |
Project byref methods to pojo implementation. |
0 |
| /recursive |
Export classes recursively. |
1 |
| /relatedclasses |
Recursively include related classes. |
0 |
| /skipstorage |
Do not export the class storage information. |
0 |
| /subclasses |
Recursively include sub-classes. |
0 |
| /system |
Include system classes. |
0 |
| /unconditionallyproject |
Project regardless of problems that may prevent code from compiling or working correctly. |
0 |
| /unicode |
Export UNICODE files. |
0 |
| /usedeepestbase |
Use deepest base in which method or property is defined for method or property definition. If P is defined in A,B, and C and A extends B extends C, then C is a deeper base for P. |
0 |
| /version4compatible |
Export CDL files that are version 4 compatible. |
0 |
ShowClassAndObject Qualifiers
| Flag |
Meaning |
Default |
| /detail |
Show detailed information. |
0 |
| /diffexport |
Do not include any time or platform information in export so the files can be run through diff/merge tools. |
0 |
| /hidden |
Show hidden classes. |
0 |
| /system |
Show system classes. |
0 |
Note:
Qualifiers may be negated by preceding the qualifier with
no as in
/nodisplaylog. Alternatively, the value of the qualifier can be specified explicitly as in
/displaylog=0.
All the qualifier shown thus far have binary values. However, there are others that require a value be explicitly given, or which collectively supply the values for several qualifiers. An example is
/checkuptodate=all. These are:
-
-
Purpose: Skip compilation of classes or expanded classes that are up to date
Values: none, all, expandedonly
-
Purpose: Provide the names of macros to define and optionally their values before compilation begins.
Example: /defines=debug,trace 1
-
Purpose: Set display qualifiers
Default: /displayerror/displaylog
-
Purpose: Alias qualifier for /predecessorclasses, /subclasses and /relatedclasses.
Values: predecessorclasses, subclasses, relatedclasses
Default: /predecessorclasses/subclasses/relatedclasses
-
Purpose: Alias qualifier for /application, /system and /percent.
Values: /application/system/percent.
-
Purpose: Causes the compiler to generate optimized output.
-
-
Purpose: Set display qualifiers
Default: /displayerror/displaylog
-
Purpose: Host that is used in JavaDoc generation
Values: System name or IP address
-
Purpose: Port that is used in JavaDoc generation
-
Purpose: The class generation mode
Note:
The defines capability is fairly restricted and should be used only to provide simple values or supply names that can be conditionally tested with #ifdef.
The following table gives the existing flag and the equivalent qualifier. Some flags map into multiple qualifiers, and also have different meanings when used for differing purposes.
Flag Qualifier Mapping
| Flag |
Group |
Qualifier |
Default |
| a |
Compiler |
/application |
1 |
| b |
Compiler |
/subclasses |
0 |
| c |
Compiler |
/compile |
0 |
| d |
Compiler |
/displayerror |
1 |
| d |
Compiler |
/displaylog |
1 |
| e |
Compiler |
/deleteextent |
0 |
| f |
Compiler |
/force |
0 |
| i |
Compiler |
/checkschema |
1 |
| k |
Compiler |
/keepsource |
0 |
| l |
Compiler |
/lock |
1 |
| p |
Compiler |
/percent |
0 |
| q |
Compiler |
/sqlonly (deprecated) |
0 |
| r |
Compiler |
/predecessorclasses |
0 |
| r |
Compiler |
/includesubpackages |
1 |
| s |
Compiler |
/system |
0 |
| u |
Compiler |
/incremental |
0 |
| v |
Compiler |
/keeporefvalid |
0 |
| y |
Compiler |
/relatedclasses |
0 |
| 4 |
Export |
/version4compatible |
0 |
| a |
Export |
/application |
1 |
| b |
Export |
/subclasses |
0 |
| d |
Export |
/displayerror |
1 |
| d |
Export |
/displaylog |
1 |
| g |
Export |
/exportselectivity |
0 |
| n |
Export |
/unicode |
0 |
| p |
Export |
/percent |
0 |
| r |
Export |
/includesubpackages |
1 |
| r |
Export |
/recursive |
1 |
| r |
Export |
/predecessorclasses |
0 |
| s |
Export |
/system |
0 |
| y |
Export |
/relatedclasses |
0 |
| d |
ShowClassAndObject |
/detail |
0 |
| h |
ShowClassAndObject |
/hidden |
0 |
| s |
ShowClassAndObject |
/system |
0 |
The
qspec is processed from left to right. The setting for a given flag or qualifier overrides the current setting whether it came from the environment defaults, or from an occurrence earlier in the
qspec.
When both flags and qualifiers appear, the flags must be placed before (to the left of) the qualifiers. This means that qualifier settings always override any flag settings.
Setting System-Wide and Process-Wide Defaults
Changes to some of the operational parameters of Caché can be made programmatically by invoking specific utility routines. For example,
$ZUTIL(68, ...) sets environment values for the life of the current process, and
$ZUTIL(69, ...) sets system-wide configuration defaults.
Other $ZUTIL routines have similar effects. Please refer to the individual routine documentation for a description of the capabilities of each.
The system-wide collation for the %String datatype can be set by changing the value of an environment global, for example,
SET ^%oddENV("collation","%String")="EXACT"
where EXACT is an allowed collation setting. The default value can be obtained via
WRITE "Default collation: "
WRITE $$DefaultCollation^%occStorageCompiler("%Library.String")