.TH float "" "" "C Keyword"
.PC "Data type"
.PP
Floating point numbers are a subset of the real numbers.
Each has a built-in radix point (or \*(QLdecimal point\*(QR) that shifts, or
\*(QLfloats\*(QR, as the value of the number changes.
It consists of the following:
one sign bit, which indicates
whether the number is positive or negative; bits that encode
the number's \fIexponent\fR; and bits that encode the number's
\fIfraction\fR, or the number upon which the exponent works.
In general, the magnitude of the number encoded depends upon the
number of bits in the exponent, whereas its precision depends upon the
number of bits in the fraction.
.PP
The ranges of values that can be held by a \*(CO
.BR float
are set in header file
.BR float.h .
.PP
The exponent often uses a
.IR bias .
This is a value that is subtracted from the exponent to yield the
power of two by which the fraction will be increased.
.PP
Floating point numbers come in two levels of precision:
single precision, called
.BR float s;
and double precision, called
.BR double s.
With most microprocessors,
.B sizeof(float)
returns four, which indicates that it is four
.BR char s
(bytes) long, and
.B sizeof(double)
returns eight.
.PP
Several formats are used to encode
.BR float s,
including IEEE, DECVAX, and BCD (binary coded decimal).
.PP
The following describes DECVAX, IEEE, and BCD formats, for your information.
.SH "DECVAX Format"
The 32 bits in a
.B float
consist of one sign bit, an eight-bit
exponent, and a 24-bit fraction, as follows.
Note that in this diagram, `s' indicates \*(QLsign\*(QR,
\*(Qle\*(Qr indicates \*(QLexponent\*(QR, and \*(Qlf\*(Ql indicates
\*(QLfraction\*(QR:
.ie p .PH 1 1 \\*(XD/float1.eps
.el \{
.ie .PH float1.xbm
.el \{
.DM
.ta 0.5i 1.5i
	=============
	| seee eeee |	\fRByte 4\fP
	|===========|
	| efff ffff |	\fRByte 3\fP
	|===========|
	| ffff ffff |	\fRByte 2\fP
	|===========|
	| ffff ffff |	\fRByte 1\fP
	=============
.DE\}
\}
.PP
The exponent has a bias of 129.
.PP
If the sign bit is set to one, the number is negative; if it is set to
zero, then the number is positive.
If the number is all zeroes, then it equals zero; an exponent and fraction
of zero plus a sign of one (\*(QLnegative zero\*(QR) is by definition
not a number.
All other forms are numeric values.
.PP
The most significant bit in the fraction is always set to one
and is not stored.
It is usually called the \*(QLhidden bit\*(QR.
.PP
The format for
.BR double s
simply adds another 32 fraction bits to the end of the
.B float
representation, as follows:
.ie p .PH 1 1 \\*(XD/float2.eps
.el \{
.ie .PH float2.xbm
.el \{
.DM
.ta 0.5i 1.5i
	=============
	| seee eeee |	\fRByte 8\fP
	|===========|
	| efff ffff |	\fRByte 7\fP
	|===========|
	| ffff ffff |	\fRByte 6\fP
	|===========|
	| ffff ffff |	\fRByte 5\fP
	|===========|
	| ffff ffff |	\fRByte 4\fP
	|===========|
	| ffff ffff |	\fRByte 3\fP
	|===========|
	| ffff ffff |	\fRByte 2\fP
	|===========|
	| ffff ffff |	\fRByte 1\fP
	=============
.DE\}
\}
.SH "IEEE Format"
The IEEE encoding of a
.B float
is the same as that in the DECVAX format.
Note, however, that the exponent has a bias of 127, rather than 129.
.PP
Unlike the DECVAX format,
IEEE format assigns special values to several floating point numbers.
Note that in the following description, a
.I tiny
exponent is one that is all zeroes, and a
.I huge
exponent is one that is all ones:
.IP \(bu 0.3i
A tiny exponent with a fraction of zero
equals zero, regardless of the setting of the sign bit.
.IP \(bu
A huge exponent with a fraction of zero
equals infinity, regardless of the setting of the sign bit.
.IP \(bu
A tiny exponent with a fraction greater than zero
is a denormalized number, i.e.,
a number that is less than the least normalized number.
.IP \(bu
A huge exponent with a fraction
greater than zero is, by definition, not a number.
These values can be used to handle special conditions.
.PP
An IEEE
.BR double ,
unlike DECVAX format, increases the number of exponent bits.
It consists of a sign bit, an 11-bit exponent, and a 53-bit fraction,
as follows:
.ie p .PH 1 1 \\*(XD/float3.eps
.el \{
.ie .PH float3.xbm
.el \{
.DM			
	=============
	| seee eeee |	\fRByte 8\fP
	|===========|
	| eeee ffff |	\fRByte 7\fP
	|===========|
	| ffff ffff |	\fRByte 6\fP
	|===========|
	| ffff ffff |	\fRByte 5\fP
	|===========|
	| ffff ffff |	\fRByte 4\fP
	|===========|
	| ffff ffff |	\fRByte 3\fP
	|===========|
	| ffff ffff |	\fRByte 2\fP
	|===========|
	| ffff ffff |	\fRByte 1\fP
	=============
.DE\}
\}
.PP
The exponent has a bias of 1,023.
The rules of encoding are the same as for
.BR float s.
.II "BCD format"
.II "binary coded decimal"
.II "packed decimal"
.SH "BCD Format"
The BCD format
(\*(QLbinary coded decimal\*(QR, also called \*(QLpacked decimal\*(QR)
is used to eliminate rounding errors
that alter the worth of an account by a fraction of a cent.
It consists of a sign, an exponent, and
a chain of four-bit numbers, each of which is defined to hold the
values zero through nine.
.PP
A BCD
.B float
has a sign bit, seven bits of exponent, and six four-bit digits.
In the following diagrams, \*(Qld\*(Qr indicates \*(QLdigit\*(QR:
.ie p .PH 1 1 \\*(XD/float4.eps
.el \{
.ie .PH float4.xbm
.el \{
.DM
	=============
	| seee eeee |	\fRByte 4\fP
	|===========|
	| dddd dddd |	\fRByte 3\fP
	|===========|
	| dddd dddd |	\fRByte 2\fP
	|===========|
	| dddd dddd |	\fRByte 1\fP
	=============
.DE\}
\}
.PP
A BCD
.B double
has a sign bit, 11 bits of exponent, and 13 four-bit digits, as
follows:
.ie p .PH 1 1 \\*(XD/float5.eps
.el \{
.ie .PH float5.xbm
.el \{
.DM
	=============
	| seee eeee |	\fRByte 8\fP
	|===========|
	| eeee dddd |	\fRByte 7\fP
	|===========|
	| dddd dddd |	\fRByte 6\fP
	|===========|
	| dddd dddd |	\fRByte 5\fP
	|===========|
	| dddd dddd |	\fRByte 4\fP
	|===========|
	| dddd dddd |	\fRByte 3\fP
	|===========|
	| dddd dddd |	\fRByte 2\fP
	|===========|
	| dddd dddd |	\fRByte 1\fP
	=============
.DE\}
\}
.PP
Passing the hexadecimal numbers A through F in a digit
yields unpredictable results.
.PP
The following rules apply when handling BCD numbers:
.IP \(bu 0.3i
A tiny exponent with a fraction of zero equals zero.
.IP \(bu
A tiny exponent with a fraction of non-zero indicates a denormalized
number.
.IP \(bu
A huge exponent with a fraction of zero indicates infinity.
.IP \(bu
A huge exponent with a fraction of non-zero is, by
definition, not a number; these non-numbers are used to indicate
errors.
.SH "COHERENT Floating Point"
\*(CO 286 uses DECVAX floating-point format.
\*(CO 386 uses IEEE floating-point format.
Please note that this does
.I not
mean that the \*(CO-386 floating-point software
fully implements the IEEE standard; for example, it does not support denormals.
.PP
To allow you to convert binary data from one floating-point format to another,
\*(CO comes with four functions with which you can convert
DECVAX-format floating-point numbers to IEEE format, and vice versa.
They are as follows:
.IP \fBdecvax_d()\fR 0.8i
Convert an IEEE \fBdouble\fR to DECVAX format.
.IP \fBdecvax_f()\fR
Convert an IEEE \fBfloat\fR to DECVAX format.
.IP \fBieee_d()\fR
Convert a DECVAX \fBdouble\fR to IEEE format.
.IP \fBieee_f()\fR
Convert a DECVAX \fBfloat\fR to IEEE format.
.PP
For details,
see their respective entries in the Lexicon.
.SH "See Also"
.Xr "C keywords," c_keyword
.Xr "data formats," data_form
.Xr "decvax_d," decvax_d
.Xr "decvax_f," decvax_f
.Xr "double," double
.Xr "ecvt()," ecvt
.Xr "em87," em87
.Xr "fcvt()," fcvt
.Xr "float," float
.Xr "float.h," float.h
.Xr "gcvt()," gcvt
.Xr "ieee_d," ieee_d
.Xr "ieee_f" ieee_f
.br
\fIThe Art of Computer Programming,\fR vol. 2, page 180\fIff\fR
.br
\*(AS, \(sc6.1.2.5
.SH Notes
.II "cpp^floating-point numbers"
.II "floating-point numbers^inclusion"
.II _DECVAX
.II _IEEE
The \*(CO-386 preprocessor implicitly defines the macro
.BR _IEEE ,
whereas the \*(CO-286 preprocessor implicitly defines the macro
.BR _DECVAX .
These can be used to conditionally include code that applies
to a specific edition of \*(CO.
If you were writing code that intensively used
floating-point numbers and you want to
compile the code under both editions of \*(CO, you can write code of
the form:
.DM
	#ifdef _DECVAX
		...
	#elif _IEEE
		...
	#endif
.DE
.PP
The C preprocessor under each edition of \*(CO will ensure that the
correct code is included for compilation.
