Format of floating point output

Discussion in 'C++' started by john, Sep 25, 2007.

  1. john

    john Guest

    I am reading TC++PL3, and on page 468, at "21.4.3 Floating-Point
    Output", it formats floating point output in the style:


    cout.setf(ios_base::scientific, ios_base::floatfield); // use scientific
    // format

    cout<< "scientific:\t"<< 1234.56789<< '\n';


    However my compiler compiles "cout.setf(ios_base::scientific)" OK.

    Does this statement affect more stream states than the original
    statement using "ios_base::floatfield", or is "ios_base::floatfield"
    usage, a redundant explicit statement?
    john, Sep 25, 2007
    #1
    1. Advertising

  2. john

    john Guest

    john wrote:
    >


    correction:

    > I am reading TC++PL3, and


    ==> on page 628,

    > at "21.4.3 Floating-Point
    > Output", it formats floating point output in the style:
    >
    >
    > cout.setf(ios_base::scientific, ios_base::floatfield); // use scientific
    > // format
    >
    > cout<< "scientific:\t"<< 1234.56789<< '\n';
    >
    >
    > However my compiler compiles "cout.setf(ios_base::scientific)" OK.
    >
    > Does this statement affect more stream states than the original
    > statement using "ios_base::floatfield", or is "ios_base::floatfield"
    > usage, a redundant explicit statement?
    john, Sep 25, 2007
    #2
    1. Advertising

  3. john

    James Kanze Guest

    On Sep 25, 12:34 pm, john <> wrote:
    > I am reading TC++PL3, and on page 468, at "21.4.3 Floating-Point
    > Output", it formats floating point output in the style:


    > cout.setf(ios_base::scientific, ios_base::floatfield); // use scientific
    > // format


    > cout<< "scientific:\t"<< 1234.56789<< '\n';


    > However my compiler compiles "cout.setf(ios_base::scientific)" OK.


    > Does this statement affect more stream states than the
    > original statement using "ios_base::floatfield", or is
    > "ios_base::floatfield" usage, a redundant explicit statement?


    Without the second parameter, it might result in an illegal
    value in the floatfield, which would result in undefined
    behavior.

    Most of the format options are boolean values, represented by
    single bits. To set a bit, the implementation simply or's the
    bit value with the existing value. For example, if you call
    std::cout.setf( std::ios::showpos ), the results will be the
    previous value, but with the showpos flag unconditionally set.
    For such boolean values, the single argument form of setf is
    appropriate, and to reset, you would normally use ios::unsetf.

    Three of the format values, however, are non-boolean (i.e. they
    have more than two possible values): floatfield, adjustfield and
    basefield. Because they have more than two values, they
    consist of more than one bit, and simple or'ing won't work.
    Consider a case, for example, where the floatfield values are
    defined as: unnamed default: 0, fixed: 1, scientific: 2. If the
    current value is fixed, and you simply or in scientific, the
    results will be 3---an illegal value, which may cause strange
    things to happen. For these fields, the two argument form of
    setf is used; this form first and's the format with the
    complement of the second argument, effectively setting all of
    the bits from the second argument to 0, before or'ing the first
    argument (which is also and'ed with the second). And the values
    floatfield, adjustfield and basefield are defined to contain all
    of the bits which need to be reset---with the example values
    above, the value would be 3.

    Note that this two argument form could be used to reset any of
    the one bit flags: call it with 0 as the first argument, and all
    of the flags to be reset as the second. This is very
    unidiomatic, however, and I wouldn't do it. Basically, in well
    written code, the following rules apply:

    -- The two argument form is always used to set the base, the
    floating point format, and the alignment. The second
    argument is always one of ios::floatfield, ios::basefield or
    ios::alignfield; the acceptable values for the first
    argument depend on the second argument (and may be 0, cast
    to the type fmtflags, although unsetf can also be used in
    this case). The two argument form is used to set one field
    at a time; although it's quite possible to set more, it's
    quite unidiomatic, which renders the code more difficult to
    read.

    -- The one argument form of setf is used to set any of the
    other values, and unsetf is used to reset them. Unlike the
    case of the two argument form, it's quite idiomatic to
    combine values here, e.g. to call setf with something like
    "ios::showpoint | ios::showpos".

    -- The "easiest" way to do complicated manipulations on the
    flags is to read them, using ios::flags(), manipulate your
    local fmtflags variable, then set the flags to the resulting
    value (using the non-const std::flags()). This is often
    used as well because you want to save the original value,
    and restore it when you're through.

    I use the third solution in my custom manipulators (which
    restore the original flags in their destructor); for some
    examples of this, you might want to look at the StateSavingManip
    and *Fmt in IO sub-system of my library
    (http://kanze.james.neuf.fr/code-en.html). (Note that most
    application code should not manipulate the flags directly, nor
    use the standard manipulators, but use rather application
    specific manipulators.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Sep 26, 2007
    #3
  4. john

    john Guest

    James Kanze wrote:
    >
    > Most of the format options are boolean values, represented by
    > single bits. To set a bit, the implementation simply or's the
    > bit value with the existing value. For example, if you call
    > std::cout.setf( std::ios::showpos ), the results will be the
    > previous value, but with the showpos flag unconditionally set.
    > For such boolean values, the single argument form of setf is
    > appropriate, and to reset, you would normally use ios::unsetf.
    >
    > Three of the format values, however, are non-boolean (i.e. they
    > have more than two possible values): floatfield, adjustfield and
    > basefield. Because they have more than two values, they
    > consist of more than one bit, and simple or'ing won't work.
    > Consider a case, for example, where the floatfield values are
    > defined as: unnamed default: 0, fixed: 1, scientific: 2. If the
    > current value is fixed, and you simply or in scientific, the
    > results will be 3---an illegal value, which may cause strange
    > things to happen. For these fields, the two argument form of
    > setf is used; this form first and's the format with the
    > complement of the second argument, effectively setting all of
    > the bits from the second argument to 0, before or'ing the first
    > argument (which is also and'ed with the second). And the values
    > floatfield, adjustfield and basefield are defined to contain all
    > of the bits which need to be reset---with the example values
    > above, the value would be 3.
    >
    > Note that this two argument form could be used to reset any of
    > the one bit flags: call it with 0 as the first argument, and all
    > of the flags to be reset as the second. This is very
    > unidiomatic, however, and I wouldn't do it. Basically, in well
    > written code, the following rules apply:
    >
    > -- The two argument form is always used to set the base, the
    > floating point format, and the alignment. The second
    > argument is always one of ios::floatfield, ios::basefield or
    > ios::alignfield; the acceptable values for the first
    > argument depend on the second argument (and may be 0, cast
    > to the type fmtflags, although unsetf can also be used in
    > this case). The two argument form is used to set one field
    > at a time; although it's quite possible to set more, it's
    > quite unidiomatic, which renders the code more difficult to
    > read.
    >
    > -- The one argument form of setf is used to set any of the
    > other values, and unsetf is used to reset them. Unlike the
    > case of the two argument form, it's quite idiomatic to
    > combine values here, e.g. to call setf with something like
    > "ios::showpoint | ios::showpos".
    >
    > -- The "easiest" way to do complicated manipulations on the
    > flags is to read them, using ios::flags(), manipulate your
    > local fmtflags variable, then set the flags to the resulting
    > value (using the non-const std::flags()). This is often
    > used as well because you want to save the original value,
    > and restore it when you're through.
    >
    > I use the third solution in my custom manipulators (which
    > restore the original flags in their destructor); for some
    > examples of this, you might want to look at the StateSavingManip
    > and *Fmt in IO sub-system of my library
    > (http://kanze.james.neuf.fr/code-en.html). (Note that most
    > application code should not manipulate the flags directly, nor
    > use the standard manipulators, but use rather application
    > specific manipulators.)



    I suppose you meant "ios_base::" where you wrote "ios::".
    john, Sep 26, 2007
    #4
  5. john

    James Kanze Guest

    On Sep 26, 11:25 am, john <> wrote:
    > James Kanze wrote:

    [...]
    > I suppose you meant "ios_base::" where you wrote "ios::".


    Not really. I learned iostreams back with the classical
    iostreams, when there was only one base class, ios, rather than
    basic_ios<>, deriving from ios_base, and I can never remember
    how things got divided up: what went into basic_ios<>, and what
    went into ios_base. But it doesn't matter, since everything in
    ios_base is also visible in basic_ios<>. So if I'm writing a
    template, I'll use basic_ios< charT, traitsT >, but most of the
    time, I'll just use ios (or wios), which is a typedef for
    basic_ios< char, char_traits< char > >.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Sep 27, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. H aka N
    Replies:
    15
    Views:
    15,647
    Ben Jones
    Mar 2, 2006
  2. Motaz Saad
    Replies:
    7
    Views:
    6,483
  3. Replies:
    4
    Views:
    1,283
    Default User
    Feb 22, 2006
  4. Saraswati lakki
    Replies:
    0
    Views:
    1,321
    Saraswati lakki
    Jan 6, 2012
  5. teeshift
    Replies:
    2
    Views:
    252
    Chris Pearl
    Dec 1, 2006
Loading...

Share This Page