Real Number Generators (float_, double_, etc.)

| Home | Libraries | People | FAQ | More

##### Real Number Generators (`float_`, `double_`, etc.)

###### Description

The `real_generator` can generate real numbers of arbitrary length and size limited by its template parameter, `Num`. The numeric base type `Num` can be a user defined numeric type such as fixed_point (fixed point reals) and bignum (unlimited precision numbers) if the type follows certain expression requirements (for more information about the requirements, see below).

###### Header

    // forwards to <boost/spirit/home/karma/numeric/real.hpp>
    #include <boost/spirit/include/karma_real.hpp>

Also, see Include Structure.

###### Namespace

Name
`boost::spirit::lit // alias: boost::spirit::karma::lit`
`boost::spirit::float_ // alias: boost::spirit::karma::float_`
`boost::spirit::double_ // alias: boost::spirit::karma::double_`
`boost::spirit::long_double // alias: boost::spirit::karma::long_double`

| Note
`lit` is reused by the String Generators, the Character Generators, and the Numeric Generators. In general, a char generator is created when you pass in a character, a string generator is created when you pass in a string, and a numeric generator is created when you use a numeric literal.

###### Synopsis

    template <typename Num, typename RealPolicies>
    struct real_generator;

###### Template parameters

Parameter | Description | Default
--- | --- | ---
`Num` | The type of the real number to generate. | `double`
`RealPolicies` | The policies to use while converting the real number. | `real_policies<Num>`

For more information about the type `RealPolicies` see below.

###### Model of

> `PrimitiveGenerator`

Notation

`num`

  Numeric literal, any real number value, or a Lazy Argument that evaluates to a real number value of type `Num`

`Num`

  Type of `num`: any real number type

###### Expression Semantics

Semantics of an expression is defined only where it differs from, or is not defined in `PrimitiveGenerator`.

Expression | Semantics
--- | ---
`lit(num)` | Generate the real number literal `num` using the default formatting (no trailing zeros, `fixed` representation for numbers `fabs(n) <= 1e5 && fabs(n) > 1e-3`, scientific representation otherwise, 3 fractional digits, sign is only printed for negative literals). This generator never fails (unless the underlying output stream reports an error).
    float_
    double_
    long_double
| Generate the real number provided by a mandatory attribute using the default formatting (no trailing zeros, `fixed` representation for numbers `fabs(n) <= 1e5 && fabs(n) > 1e-3`, scientific representation otherwise, 3 fractional digits, sign is only printed for negative literals). This generator never fails (unless the underlying output stream reports an error).
    float_(num)
    double_(num)
    long_double(num)
| Generate the real point number provided by the immediate literal value the generator is initialized from using the default formatting (no trailing zeros, `fixed` representation for numbers `fabs(n) <= 1e5 && fabs(n) > 1e-3`, scientific representation otherwise, 3 fractional digits, sign is only printed for negative literals). If this generator has an associated attribute it succeeds only if the attribute is equal to the immediate literal (unless the underlying output stream reports an error). Otherwise this generator fails and does not generate any output.

All generators listed in the table above (except `lit(num)`) are predefined specializations of the `real_generator<Num, RealPolicies>` basic real number generator type described below. It is possible to directly use this type to create real number generators using a wide range of formatting options.

Expression | Semantics
--- | ---
    real_generator<
        Num, RealPolicies
    >()
| Generate the real number of type `Num` provided by a mandatory attribute using the specified `RealPolicies`. This generator never fails (unless the underlying output stream reports an error).
    real_generator<
        Num, RealPolicies
    >()(num)
| Generate the real number of type `Num` provided by the immediate literal value the generator is initialized from using the specified `RealPolicies`. If this generator has an associated attribute it succeeds only if the attribute is equal to the immediate literal (unless the underlying output stream reports an error). Otherwise this generator fails and does not generate any output.

###### Additional Requirements

The following list enumerates the requirements which must be met in order to use a certain type `Num` to instantiate a `real_generator<Num, Policies>`.

In order to be usable as the first template parameter for `real_generator<>` the type `Num` must have defined:

- comparison operators for: `<`, `<=`, `==`, `!=`, `>`, and `>=`
- numeric operators for: `+`, `-`, `/`, `*`, and `%`
- functions implementing the interface and the semantics of: `std::fmod`, `std::pow`, `std::log10`, `std::lround`, `std::ltrunc`, `std::modf`, `std::floor`, and `std::ceil`. These need to be defined in a way so that they will be found using argument dependent lookup (ADL).
- a valid specialization of the type `std::numeric_limits<Num>` allowing for numeric property inspection.

###### Attributes

Expression | Attribute
--- | ---
`lit(num)` | `unused`
`float_` | `float`, attribute is mandatory (otherwise compilation will fail)
`float_(num)` | `float_`, attribute is optional, if it is supplied, the generator compares the attribute with `num` and succeeds only if both are equal, failing otherwise.
`double_` | `double`, attribute is mandatory (otherwise compilation will fail)
`double_(num)` | `double`, attribute is optional, if it is supplied, the generator compares the attribute with `num` and succeeds only if both are equal, failing otherwise.
`long_double` | `long double`, attribute is mandatory (otherwise compilation will fail)
`long_double(num)` | `long double`, attribute is optional, if it is supplied, the generator compares the attribute with `num` and succeeds only if both are equal, failing otherwise.
    real_generator<
        Num, Policies
    >()
| `Num`, attribute is mandatory (otherwise compilation will fail)
    real_generator<
        Num, Policies
    >()(num)
| `Num`, attribute is optional, if it is supplied, the generator compares the attribute with `num` and succeeds only if both are equal, failing otherwise.

| Note
In addition to their usual attribute of type `Num` all listed generators accept an instance of a `boost::optional<Num>` as well. If the `boost::optional<>` is initialized (holds a value) the generators behave as if their attribute was an instance of `Num` and emit the value stored in the `boost::optional<>`. Otherwise the generators will fail.

###### Real Number Formatting Policies

If special formatting of a real number is needed, overload the policy class `real_policies<Num>` and use it as a template parameter to the `real_generator<>` real number generator. For instance:

    // define a new real number formatting policy
    template <typename Num>
    struct scientific_policy : real_policies<Num>
    {
        // we want the numbers always to be in scientific format
        static int floatfield(Num n) { return fmtflags::scientific; }
    };

    // define a new generator type based on the new policy
    typedef real_generator<double, scientific_policy<double> > science_type;
    science_type const scientific = science_type();

    // use the new generator
    generate(sink, science_type(), 1.0);  // will output: 1.0e00
    generate(sink, scientific, 0.1);      // will output: 1.0e-01

The template parameter `Num` should be the type to be formatted using the overloaded policy type. At the same time `Num` will be used as the attribute type of the created real number generator.

###### Real Number Formatting Policy Expression Semantics

A real number formatting policy should expose the following variables and functions:

Expression | Description
--- | ---
    template <typename Inserter
      , typename OutputIterator
      , typename Policies>
    bool call (OutputIterator& sink, Num n
      , Policies const& p);
| This is the main function used to generate the output for a real number. It is called by the real generator in order to perform the conversion. In theory all of the work can be implemented here, but the easiest way is to use existing functionality provided by the type specified by the template parameter `Inserter`. The default implementation of this functions is:
    template <typename Inserter, typename OutputIterator
      , typename Policies>
    static bool
    call (OutputIterator& sink, Num n, Policies const& p)
    {
        return Inserter::call_n(sink, n, p);
    }
`sink` is the output iterator to use for generation `n` is the real number to convert `p` is the instance of the policy type used to instantiate this real number generator.
    bool force_sign(Num n);
| The default behavior is to not to require generating a sign. If the function `force_sign()` returns true, then all generated numbers will have a sign (`'+'` or `'-'`, zeros will have a space instead of a sign). `n` is the real number to output. This can be used to adjust the required behavior depending on the value of this number.
    bool trailing_zeros(Num n);
| Return whether trailing zero digits have to be emitted in the fractional part of the output. If set, this flag instructs the real number generator to emit trailing zeros up to the required precision digits (as returned by the `precision()` function). `n` is the real number to output. This can be used to adjust the required behavior depending on the value of this number.
    int floatfield(Num n);
| Decide, which representation type to use in the generated output. By default all numbers having an absolute value of zero or in between `0.001` and `100000` will be generated using the fixed format, all others will be generated using the scientific representation. The `trailing_zeros()` can be used to force the output of trailing zeros in the fractional part up to the number of digits returned by the `precision()` member function. The default is not to generate the trailing zeros. `n` is the real number to output. This can be used to adjust the formatting flags depending on the value of this number. The return value has to be either `fmtflags::scientific` (generate real number values in scientific notation) or `fmtflags::fixed` (generate real number values in fixed-point notation).
    unsigned precision(Num n);
| Return the maximum number of decimal digits to generate in the fractional part of the output. `n` is the real number to output. This can be used to adjust the required precision depending on the value of this number. If the trailing zeros flag is specified the fractional part of the output will be 'filled' with zeros, if appropriate. Note: If the trailing_zeros flag is not in effect additional semantics apply. See the description for the `fraction_part()` function below. Moreover, this precision will be limited to the value of `std::numeric_limits<T>::digits10 + 1`.
    template <typename OutputIterator>
    bool integer_part(OutputIterator& sink
      , Num n, bool sign, bool force_sign);
| This function is called to generate the integer part of the real number. `sink` is the output iterator to use for generation `n` is the absolute value of the integer part of the real number to convert (always non-negative) `sign` is the sign of the overall real number to convert. `force_sign` is a flag indicating whether a sign has to be generated even for non-negative numbers (this is the same as has been returned from the function `force_sign()` described above) The return value defines the outcome of the whole generator. If it is `false`, no further output is generated, immediately returning `false` from the calling `real_generator` as well. If it is `true`, normal output generation continues.
    template <typename OutputIterator>
    bool dot(OutputIterator& sink, Num n,
      unsigned precision);
| This function is called to generate the decimal point. `sink` is the output iterator to use for generation `n` is the fractional part of the real number to convert. Note that this number is scaled such, that it represents the number of units which correspond to the value returned from the `precision()` function earlier. I.e. a fractional part of `0.01234` is represented as `1234` when the function `precision()` returned `5`. `precision` is the number of digits to emit as returned by the function `precision()` described above This is given to allow to decide, whether a decimal point has to be generated at all. Note: If the `trailing_zeros` flag is not in effect additional comments apply. See the description for the `fraction_part()` function below. The return value defines the outcome of the whole generator. If it is `false`, no further output is generated, immediately returning `false` from the calling `real_generator` as well. If it is `true`, normal output generation continues.
    template <typename OutputIterator>
    bool fraction_part(OutputIterator& sink, Num n
      , unsigned adjprec, unsigned precision);
| This function is called to generate the fractional part of the number. `sink` is the output iterator to use for generation `n` is the fractional part of the real number to convert. Note that this number is scaled such, that it represents the number of units which correspond to the value returned from the `precision()` function earlier. I.e. a fractional part of `0.01234` is represented as `1234` when the function `precision()` returned `5`. `adjprec` is the corrected number of digits to emit (see note below) `precision` is the number of digits to emit as returned by the function `precision()` described above Note: If `trailing_zeros()` returns `false` the `adjprec` parameter will have been corrected from the value the `precision()` function returned earlier (defining the maximal number of fractional digits) in the sense, that it takes into account trailing zeros. I.e. a real number `0.0123` and a value of `5` returned from `precision()` will result in: `trailing_zeros()` returned `false`: `n` will be `123`, and `adjprec` will be `4` (as we need to print `0123`) `trailing_zeros()` returned `true`: `n` will be `1230`, and `adjprec` will be `5` (as we need to print `01230`) The missing preceding zeros in the fractional part have to be supplied by the implementation of this policy function. The return value defines the outcome of the whole generator. If it is `false`, no further output is generated, immediately returning `false` from the calling `real_generator` as well. If it is `true`, normal output generation continues.
    template <typename CharEncoding,
        typename Tag, typename OutputIterator>
    bool exponent(
        OutputIterator& sink, long n);
| This function is called to generate the exponential part of the number (this is called only if the `floatfield()` function returned the `fmtflags::scientific` flag). `sink` is the output iterator to use for generation `n` is the (signed) exponential part of the real number to convert. The template parameters `CharEncoding` and `Tag` are either of the type `unused_type` or describe the character class and conversion to be applied to any output possibly influenced by either the `lower[]` or `upper[]` directives. The return value defines the outcome of the whole generator. If it is `false`, no further output is generated, immediately returning `false` from the calling `real_generator` as well. If it is `true`, normal output generation continues.
    template <typename CharEncoding
      , typename Tag, typename OutputIterator>
    bool nan (OutputIterator& sink, Num n
      , bool force_sign);
| This function is called whenever the number to print is a non-normal real number of type `NaN`. `sink` is the output iterator to use for generation `n` is the (signed) real number to convert `force_sign` is a flag indicating whether a sign has to be generated even for non-negative numbers (this is the same as has been returned from the function `force_sign()` described above) The template parameters `CharEncoding` and `Tag` are either of the type `unused_type` or describe the character class and conversion to be applied to any output possibly influenced by either the `lower[]` or `upper[]` directives. The return value defines the outcome of the whole generator. If it is `false`, no further output is generated, immediately returning `false` from the calling `real_generator` as well. If it is `true`, normal output generation continues.
    template <typename CharEncoding
      , typename Tag, typename OutputIterator>
    bool inf (OutputIterator& sink, Num n
      , bool force_sign);
| This function is called whenever the number to print is a non-normal real number of type `Inf`. `sink` is the output iterator to use for generation `n` is the (signed) real number to convert `force_sign` is a flag indicating whether a sign has to be generated even for non-negative numbers (this is the same as has been returned from the function `force_sign()` described above) The template parameters `CharEncoding` and `Tag` are either of the type `unused_type` or describe the character class and conversion to be applied to any output possibly influenced by either the `lower[]` or `upper[]` directives. The return value defines the outcome of the whole generator. If it is `false`, no further output is generated, immediately returning `false` from the calling `real_generator` as well. If it is `true`, normal output generation continues.

| Tip
The easiest way to implement a proper real number formatting policy is to derive a new type from the the type `real_policies<>` while overriding the aspects of the formatting which need to be changed.

###### Complexity

> O(N), where `N` is the number of digits needed to represent the generated real number.

###### Example

| Note
The test harness for the example(s) below is presented in the Basics Examples section.

Some includes:

    #include <boost/spirit/include/karma.hpp>
    #include <boost/spirit/include/support_utree.hpp>
    #include <boost/spirit/include/phoenix_core.hpp>
    #include <boost/spirit/include/phoenix_operator.hpp>
    #include <boost/fusion/include/std_pair.hpp>
    #include <iostream>
    #include <string>

Some using declarations:

    using boost::spirit::karma::double_;
    using boost::spirit::karma::lit;

Basic usage of an `double_` generator:

    test_generator("2.0", lit(2.0));
    test_generator("2.0", double_(2));
    test_generator_attr("2.0", double_(2.0), 2.0);
    test_generator_attr("", double_(2.0), 3.0);    // fails (as 2.0 != 3.0)!
    test_generator_attr("-2.0", double_, -2.0);

    test_generator_attr("1.234e05", double_, 1234.0e2);
    test_generator_attr("1.234e-06", double_, 0.000001234);