Home|Management Portal|Index
Technical Articles
InterSystems Product Miscellany
« »
   
Server:docs.intersystems.com
Instance:CACHE20081
User:UnknownUser
 
-
Search:    

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.
$HOROLOG Day-1
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." 
Numeric Computing
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é Native Format
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 64–bit 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.
$DOUBLE Format
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:
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:
For further details, please refer to the standard and its references to other explanatory documentation.
Native Versus $DOUBLE
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.
Numbers Versus Strings
According to the M Standard (ANSI/MDC X11.1–1994), 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))
     }
 
Flags And Qualifiers
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()
 
and
 Do $SYSTEM.OBJ.ShowQualifiers()
Flags
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.
Qualifiers
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
These qualifiers are given in the qspec as they appear, for example, “/compile/displayerror/force/subclasses”. No spaces are allowed between qualifiers.
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”.
Other Qualifiers
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:
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.
Qualifiers For Flags
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
Order Of Processing
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 Defaults
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.
System-Wide Collation
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")