<?xml version="1.0"?>

<!--
	description:

		"Scientific Format"

	library: "Gobo Eiffel String Library"
	copyright: "Copyright (c) 2004, Berend de Boer and others"
	license: "MIT License"
	date: "$Date$"
	revision: "$Revision$"

-->

<chapter xmlns="http://www.gobosoft.com/eiffel/gobo/documentation" id="string/formatter/scientific_format">

<chapterinfo>
	<copyright>
		<year>2004-2005</year>
		<holder>Berend de Boer</holder>
	</copyright>
	<author>
		<firstname>Berend</firstname><surname>de Boer</surname>
	</author>
	<email>berend@pobox.com</email>
	<date>7 March 2005</date>
</chapterinfo>

<title>Scientific Format</title>

<para>
The formatting specifications, which consist of optional and required fields, have 
the following form:
</para>

<para>
<blockquote>
<synopsis>
$[flags][minimum width][.precision]typechar
</synopsis>
</blockquote>
</para>

<para>
Each field of the formatting specification is a single character or a number 
indicating a particular format option. The simplest formatting specification contains 
only the escape character and a typechar (for example, 
<quote>$s</quote>). To print an escape character, write it twice (e.g. 
<quote>$$</quote>).
</para>

<para>
The optional fields, which appear before the type character, control other 
aspects of the formatting:
</para>

<section id="type_character"><title>Type character</title>

<para>
The type character is required. It determines whether the associated parameter is 
interpreted as a character, as a string, or as a number.
</para>

<para>
The following typechars are available in class <classname>ST_SCIENTIFIC_FORMATTER</classname>:
</para>

<table>
	<title>Recognized type characters</title>
	<tgroup cols="3">
	<thead>
		<row>
			<entry>Typechar</entry>
			<entry>Class</entry>
			<entry>Description</entry>
		</row>
	</thead>
	<tbody>
		<row>
			<entry>c</entry>
			<entry><classname>CHARACTER</classname></entry>
			<entry>Single character.</entry>
		</row>
		<row>
			<entry>b</entry>
			<entry><classname>BOOLEAN</classname></entry>
			<entry><quote>true</quote> or <quote>false</quote> strings.</entry>
		</row>
		<row>
			<entry>B</entry>
			<entry><classname>BOOLEAN</classname></entry>
			<entry><quote>True</quote> or <quote>False</quote> strings.</entry>
		</row>
		<row>
			<entry>d</entry>
			<entry><classname>INTEGER</classname></entry>
			<entry>Signed decimal integer.</entry>
		</row>
		<row>
			<entry>e</entry>
			<entry><classname>DOUBLE</classname></entry>
			<entry>Signed value having the form <quote>[-]d.dddde[sign]ddd</quote> 
				where d is a single decimal digit, dddd is one or more decimal 
				digits, ddd is exactly three decimal digits, and sign is 
				'+' or '-'.</entry>
		</row>
		<row>
			<entry>E</entry>
			<entry><classname>DOUBLE</classname></entry>
			<entry>As 'e', but using the uppercase character 'E'.</entry>
		</row>
		<row>
			<entry>f</entry>
			<entry><classname>DOUBLE</classname></entry>
			<entry>Signed value having the form <quote>[-]dddd.dddd</quote>, where
				<quote>dddd</quote> is one or more decimal digits. The number of 
				digits before the decimal point depends on the magnitude of the
				number, and the number of digits after the decimal point
				depends on the requested precision.</entry>
		</row>
		<row>
			<entry>g</entry>
			<entry><classname>DOUBLE</classname></entry>
			<entry>Signed value printed in 'f' or 'e' format, whichever
				is more compact for the given value and precision. The e
				format is used only when the exponent of the value is
				less than -4 or greater than or equal to the precision
				option. Trailing zeros are truncated, and the decimal
				point appears only if one or more digits follow it.</entry>
		</row>
		<row>
			<entry>G</entry>
			<entry><classname>DOUBLE</classname></entry>
			<entry>As 'g', but using the 'E' instead of 'e'.</entry>
		</row>
		<row>
			<entry>i</entry>
			<entry><classname>INTEGER</classname></entry>
			<entry>Signed decimal integer.</entry>
		</row>
		<row>
			<entry>o</entry>
			<entry><classname>INTEGER</classname></entry>
			<entry>Unsigned octal integer.</entry>
		</row>
		<row>
			<entry>p</entry>
			<entry><classname>POINTER</classname></entry>
			<entry>Hexadecimal pointer output.</entry>
		</row>
		<row>
			<entry>s</entry>
			<entry><classname>STRING</classname></entry>
			<entry>Character string; Characters are printed up to the end of string 
				or until the precision value is reached.</entry>
		</row>
		<row>
			<entry>u</entry>
			<entry><classname>INTEGER</classname></entry>
			<entry>Unsigned decimal integer.</entry>
		</row>
		<row>
			<entry>x</entry>
			<entry><classname>INTEGER</classname></entry>
			<entry>Unsigned hexadecimal integer, using <quote>abcdef</quote>.</entry>
		</row>
		<row>
			<entry>X</entry>
			<entry><classname>INTEGER</classname></entry>
			<entry>Unsigned hexadecimal integer, using <quote>ABCDEF</quote>.</entry>
		</row>
	</tbody>
	</tgroup>
</table>

<para>
Note that this list can be extended. Also note that only letters between a..z and 
A..Z are legal.
</para>

</section>

<section id="flags"><title>Flags</title>

<para>
Flags are optional character or characters that control justification of output 
and printing of signs, blanks. More than one flag can appear in a formatting
specification, but they must be compatible with each other.
</para>

<table>
	<title>Flags overview</title>
	<tgroup cols="3">
	<thead>
		<row>
			<entry>Flag</entry>
			<entry>Meaning</entry>
			<entry>Default</entry>
		</row>
	</thead>
	<tbody>
		<row>
			<entry>^&#x2003;&#x2003;</entry>
			<entry>Center the formatted parameter within the given field width</entry>
			<entry>Right align</entry>
		</row>
		<row>
			<entry>-</entry>
			<entry>Left align the formatted parameter within the given field width.</entry>
			<entry>Right align</entry>
		</row>
		<row>
			<entry>+</entry>
			<entry>Prefix the formatted parameter with a sign (+ or -) if it has 
				a signed type.</entry>
			<entry>Sign appears only for negative values (-).</entry>
		</row>
		<row>
			<entry>0</entry>
			<entry>Zeros are added until the minimum width is reached.</entry>
			<entry>No padding.</entry>
		</row>
		<row>
			<entry>_&#x2003;</entry>
			<entry>Prefix the formatted parameter with a blank (shown with an underscore here) if 
				it is signed and positive.</entry>
			<entry>No blank appears.</entry>
		</row>
	</tbody> 
	</tgroup>
</table>

<para>
The following flag combinations: 
<itemizedlist>
	<listitem><para>
		'&#x2003;' after '+'
	</para></listitem>
	<listitem><para>
		'0' with '-'
	</para></listitem>
	<listitem><para>
		'0' with '^'
	</para></listitem>
	<listitem><para>
		'-' with '^'
	</para></listitem>
</itemizedlist>
are not allowed.
</para>

</section>

<section id="precision"><title>Minimum width</title>

<para>
The width is an optional number that specifies the minimum number of 
characters in the formatted parameter.
</para>

<para>
The width argument is a non-negative decimal integer controlling the minimum 
number of characters printed. If the number of characters in the formatted parameter is 
less than the specified width, blanks are added to the left or to the right
- depending on whether the '-' flag (for left alignment) is specified - 
until the minimum width is reached. If width is prefixed with 0, zeros are added 
until the minimum width is reached (not useful for left-aligned numbers).
</para>

<para>
The width specification never causes a value to be truncated. If the number of 
characters in the formatted parameter is greater than the specified width, or if width 
is not given, all characters of the value are printed (subject to the precision 
specification).
</para>

<para>
If the width specification is an asterisk (*), an integer from the parameter 
list provides the value. The width option must precede the parameter being 
formatted in the parameter list. A non-existent or small field width does not cause 
the truncation of a field; if the formatted parameter is wider than the field 
width, the field expands to contain all characters.
</para>

</section>

<section id="precision"><title>Precision</title>

<para>
The third optional field of the format specification is the precision 
specification. It is made up of a non-negative decimal integer, preceded by a period 
'.', which specifies the number of characters to be printed, the number of 
decimal places, or the number of significant digits (see table below). Unlike the 
width specification, the precision specification can cause either truncation of 
the formatted parameter or rounding of a floating-point parameter. If precision is specified 
as <integer>0</integer> and the parameter to be formatted is <integer>0</integer>, 
the result is no characters output:
</para>

<para>
<informalexample>
<programlisting>
<featurecall>
	<featurename>print</featurename>
	<arguments>
		<argument><featurecall>
			<featurename>format</featurename> 
			<arguments>
				<argument>"$.0d"</argument>
				<argument>&lt;&lt;<featurecall>
					<featurename>integer_cell</featurename>
					<arguments><argument><integer>0</integer></argument></arguments>
				</featurecall>&gt;&gt;</argument>
			</arguments>
		</featurecall></argument>
	</arguments>
</featurecall> -- No characters output
</programlisting>
</informalexample>
</para>

<para>
If the precision specification is an asterisk (*), an integer from the 
parameter list provides the value. The precision option must precede the 
parameter being formatted in the parameter list.
</para>

<para>
The table below details how precision affects type:
</para>

<table>
	<title>How precision affects type</title>
	<tgroup cols="3">
	<thead>
		<row>
			<entry>Type</entry>
			<entry>Meaning</entry>
			<entry>Default</entry>
		</row>
	</thead>
	<tbody>
		<row>
			<entry>c</entry>
			<entry>The precision has no effect.</entry>
			<entry>Character is printed.</entry>
		</row>
		<row>
			<entry>b, B</entry>
			<entry>The precision has no effect.</entry>
			<entry>"[tT]rue"/"[fF]alse" is printed.</entry>
		</row>
		<row>
			<entry>d, i, u, o, x</entry>
			<entry>The precision specifies the minimum number of digits to be 
				printed. If the number of digits in the parameter is less than 
				precision, the output value is padded on the left with zeros.</entry>
			<entry>The value is not truncated when the number of digits exceeds 
				precision. Default precision is <integer>1</integer>.</entry>
		</row>
		<row>
			<entry>e</entry>
			<entry>The precision specifies the number of digits to
				be printed after the decimal point. The last printed
				digit is rounded.</entry>
			<entry>Default precision is <integer>6</integer>; if precision is 
				<integer>0</integer>, no decimal point is printed.</entry>
		</row>
		<row>
			<entry>f</entry>
			<entry>The precision value specifies the number of digits after the 
				decimal point. If a decimal point appears, at least one digit 
				appears before it. The value is rounded to the appropriate 
				number of digits.</entry>
			<entry>Default precision is <integer>6</integer>; if precision is 
				<integer>0</integer>, no decimal point is printed.</entry>
		</row>
		<row>
			<entry>g</entry>
			<entry>The precision specifies the maximum number of significant 
				digits printed.</entry>
			<entry>Six significant digits are printed, with any trailing zeros 
				truncated.</entry>
		</row>
		<row>
			<entry>s</entry>
			<entry>The precision specifies the maximum number of characters to be 
				printed. Characters in excess of precision are not printed.</entry>
			<entry>Characters are printed until end of string.</entry>
		</row>
	</tbody>
	</tgroup>
</table>

</section>

</chapter>
