Data types are sets of values combined with sets of
allowable
operations that apply to each member of a specific data type. The members
of a data type can assume only those values and return only those functions
contained in that data type.
SAS/C Release 7.00 supports the long
long data type, both signed and unsigned. This data type
is used for 64-bit (8-byte) integers. To specify either type in a declaration
or cast, use the keyword long twice, and the unsigned keyword when necessary, as shown in the following
example:
long long taxes();
if (taxes() >= (unsigned long long) my_salary)
panic();
A signed long long can
hold any integer value between -9223372036854775808 (-2
to the 63rd power) to 9223372036854775807 (2
to the 63rd power - 1). These values are associated with the symbols LLONG_MIN and
LLONG_MAX (defined in limits.h), respectively. An unsigned long
long can hold any value between 0 and 18446744073709551615 (2
to the 64th power - 1). This value is associated with the symbol ULLONG_MAX defined in limits.h.
Constants in
the range of the long long types may be written in decimal, octal, or hexadecimal form,
the same as other integer constants. If a constant is too large to be an unsigned
long, it is assumed to be a long long or unsigned long long constant. long long
constants in the range of a 32-bit integer type can be written using the suffix
LL (for signed long long) or ULL (for unsigned long long). Examples of long long constants are 14LL
and
0XFF00FF00ULL.
long long values can
be converted to and from all other numeric types, sometimes with a loss of
accuracy. Note that a long long, with 63 bits
of accuracy, is more accurate than a double,
with 53-56 bits, and that therefore conversions from long long to double may well lose precision.
Note that if an expression has a double (or float) operand and a long long
operand, the long long operand is converted
to a double. You should use a cast if this
is not the outcome you want.
Expressions with long long
or unsigned long long operands behave the way
a C programmer would expect. The result of such an operation having only
integral operands is a signed or unsigned long long (with a couple of exceptions), unsigned if any operand
(after promotion) was unsigned, and otherwise signed. The main exception to the
rule stated above has to do with the shift operator. If the first operand
of a shift operand is long long, the result
will be long long, but the type of the second
operand has no effect on the type of the result. Thus, 1L << 10LL has
type long, but 1LL << 10L has type long long.
long long bit fields
are not supported. long long enum values are
also not supported.
long long variables are
ordinarily aligned on a doubleword boundary. The SAS/C extension _ _noalignmem can be used to have
unaligned long long members in a structure.
Subscript expressions are always converted to int. An expression
such as b[0x100000001LL] is syntactically valid,
but has the same meaning as b[(int)0x100000001LL] or, equivalently, b[1], which may not have been
the programmer's intent.
The control variable of a switch statement may have long long type.
The implementation
of long long
in SAS/C is compatible with the ISO 1999 C Language Standard.
The addition of the long long
data type is an extension to the ANSI/ISO C language standard of 1989. In
most cases, the existence of long long does
not change the meaning of existing standard-conforming programs. However,
in some cases, such changes are possible. These changes can occur mostly
because of the potentially different meanings of arithmetic constants. Take
the following example:
long m = (0xffffffff * 0xffffffff) / 0xffffffff;
Prior to SAS/C Release 7.00, the initial value of m
was 0. For Release 7.00 and beyond, the value will be -1, because 0xffffffff is
now treated as a signed long long constant
rather than as an unsigned long constant.
Another way in which the addition of the long long data type could
affect existing standard-conforming
programs is that certain library headers have been updated to include prototypes
for long long functions. Any program that uses
one of these names for a different purpose and includes the corresponding
header file will probably not compile or execute. The compiler define option can be used in such a case to define the feature
test macro _SASC_HIDE_LLLIB,
which suppresses these prototypes.
Copyright © 2001
by SAS Institute Inc., Cary, NC, USA. All rights reserved.