conversion between string and numerical value

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Aman JIANG

    #1

    conversion between string and numerical value

    hi

    i need a fast way to do lots of conversion that between
    string and numerical value(integer, float, double...), and
    boost::lexical_ cast is useless, because it runs for a long time,
    (about 60 times slower than corresponding C functions)
    it's too expensive for my program.

    is there any way([template] library?) to do this fast and safely,
    please ?
    (old C-style functions is unbecoming)

  • Victor Bazarov

    #2
    Re: conversion between string and numerical value

    Aman JIANG wrote:
    i need a fast way to do lots of conversion that between
    string and numerical value(integer, float, double...), and
    boost::lexical_ cast is useless, because it runs for a long time,
    (about 60 times slower than corresponding C functions)
    it's too expensive for my program.
    So, use the C functions.
    is there any way([template] library?) to do this fast and safely,
    please ?
    I don't know of any, but should be relatively easy for you to roll
    your own, no?
    (old C-style functions is unbecoming)
    Why?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • Michal Nazarewicz

      #3
      Re: conversion between string and numerical value

      Aman JIANG <AmanJIANG@gmai l.comwrites:
      hi
      >
      i need a fast way to do lots of conversion that between
      string and numerical value(integer, float, double...), and
      boost::lexical_ cast is useless, because it runs for a long time,
      (about 60 times slower than corresponding C functions)
      it's too expensive for my program.
      >
      is there any way([template] library?) to do this fast and safely,
      please ?
      (old C-style functions is unbecoming)
      How about:

      #v+
      std::string toString(long value) {
      char buffer[100];
      sprintf(buffer, "%ld", value);
      return std::string(buf fer);
      }

      std::string toString(unsign ed long value) {
      char buffer[100];
      sprintf(buffer, "%lu", value);
      return std::string(buf fer);
      }

      long atol(std::strin g str) { return atol(str.c_str( )); }
      double atof(std::strin g str) { return atof(str.c_str( )); }
      #v-

      It's C++ all right.

      --
      Best regards, _ _
      .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
      ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
      ooo +--<mina86*tlen.pl >---<jid:mina86*chr ome.pl>--ooO--(_)--Ooo--

      Comment

      • Aman JIANG

        #4
        Re: conversion between string and numerical value

        On 9 20 , 12 47 , "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
        (old C-style functions is unbecoming)
        >
        Why?
        because its style, it doesn't support wchar_t, and template and so
        on...

        Comment

        • Aman JIANG

          #5
          Re: conversion between string and numerical value

          On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.pl wrote:
          How about:
          >
          #v+
          std::string toString(long value) {
          char buffer[100];
          sprintf(buffer, "%ld", value);
          return std::string(buf fer);
          >
          }
          >
          std::string toString(unsign ed long value) {
          char buffer[100];
          sprintf(buffer, "%lu", value);
          return std::string(buf fer);
          >
          }
          >
          long atol(std::strin g str) { return atol(str.c_str( )); }
          double atof(std::strin g str) { return atof(str.c_str( )); }
          #v-
          >
          It's C++ all right.
          thank you :)
          char buffer[100];
          that "100" is a magic number.
          and this cannot support wchar_t, too :(

          Comment

          • Michal Nazarewicz

            #6
            Re: conversion between string and numerical value

            Aman JIANG <AmanJIANG@gmai l.comwrites:
            On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.pl wrote:
            >How about:
            >>
            >#v+
            >std::string toString(long value) {
            > char buffer[100];
            > sprintf(buffer, "%ld", value);
            > return std::string(buf fer);
            >}
            >>
            >std::string toString(unsign ed long value) {
            > char buffer[100];
            > sprintf(buffer, "%lu", value);
            > return std::string(buf fer);
            >}
            One more:

            std::string toString(double value) {
            char buffer[100];
            sprintf(buffer, "%f", value);
            return std::string(buf fer);
            }
            >long atol(std::strin g str) { return atol(str.c_str( )); }
            >double atof(std::strin g str) { return atof(str.c_str( )); }
            >#v-
            >>
            >It's C++ all right.
            >
            thank you :)
            > char buffer[100];
            that "100" is a magic number.
            Yep, its a number long enough to hold a string representation of
            a (unsigned) long value.
            and this cannot support wchar_t, too :(
            Uhm? You can rewrite it to support it. Just replace char by wchar_t and
            sprintf with swprintf but I'm not sure if you really need it since the
            value is converted into std::string anyways.

            --
            Best regards, _ _
            .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
            ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
            ooo +--<mina86*tlen.pl >---<jid:mina86*chr ome.pl>--ooO--(_)--Ooo--

            Comment

            • Michael DOUBEZ

              #7
              Re: conversion between string and numerical value

              Michal Nazarewicz a écrit :
              Aman JIANG <AmanJIANG@gmai l.comwrites:
              >
              >On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.pl wrote:
              >>How about:
              >>>
              >>#v+
              >>std::string toString(long value) {
              >> char buffer[100];
              >> sprintf(buffer, "%ld", value);
              >> return std::string(buf fer);
              >>}
              >>[snip]
              >>It's C++ all right.
              >thank you :)
              >> char buffer[100];
              >that "100" is a magic number.
              >
              Yep, its a number long enough to hold a string representation of
              a (unsigned) long value.
              You can use numeric_limits< >::digits10 to fit the size to you type.

              // add one for \0 and for additional digit
              // add one more for sign with signed
              char buffer [std::numeric_li mits<unsigned long>::digits10 + 2];

              In fact, with traits, it should be possible to write a template.

              Michael

              Comment

              • James Kanze

                #8
                Re: conversion between string and numerical value

                On Sep 20, 1:55 pm, Michal Nazarewicz <min...@tlen.pl wrote:
                Aman JIANG <AmanJI...@gmai l.comwrites:
                On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.pl wrote:
                How about:
                #v+
                std::string toString(long value) {
                char buffer[100];
                sprintf(buffer, "%ld", value);
                return std::string(buf fer);
                }
                std::string toString(unsign ed long value) {
                char buffer[100];
                sprintf(buffer, "%lu", value);
                return std::string(buf fer);
                }
                One more:
                std::string toString(double value) {
                char buffer[100];
                sprintf(buffer, "%f", value);
                return std::string(buf fer);
                }
                long atol(std::strin g str) { return atol(str.c_str( )); }
                double atof(std::strin g str) { return atof(str.c_str( )); }
                #v-
                It's C++ all right.
                thank you :)
                char buffer[100];
                that "100" is a magic number.
                Yep, its a number long enough to hold a string representation of
                a (unsigned) long value.
                On some machines. There's no guarantee (although it's likely to
                be sufficient in the near future).

                It's not necessarily large enough to hold a "%f" conversion of a
                float, and it's not large enough to hold a "%f" conversion of a
                double on the machines I usually work on.

                I might add that there is no guarantee that sprintf is faster
                than boost::lexical_ cast, although it's likely *if*
                boost::lexical_ cast doesn't have partial specializations for
                std::string (since in the general case, boost::lexical_ cast must
                do two conversions, and not just one).

                More generally, you might try:

                std::string
                toString( double value )
                {
                std::ostringstr eam s ;
                s << value ;
                return s.str() ;
                }

                or if that's too slow:

                std::string
                toString( double value )
                {
                char buffer[ 100 ] ;
                std::ostrstream s ;
                s << value << std::ends ;
                assert( s ) ;
                return buffer ;
                }

                (This will at least cause an assertion failure, rather than
                undefined behavior, if the converted string requires more than
                99 characters. You can, of course, replace the assertion with
                any other error handling you wish.)

                If all else fails, you can try snprintf, which is not standard
                C++, but is standard C99, and probably available with your
                implementation (and allows for error checking as well).

                Also, you probably want to use the "%g" format (the default for
                iostream), unless you know that the input is in a very limited
                range.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                • James Kanze

                  #9
                  Re: conversion between string and numerical value

                  On Sep 20, 2:15 pm, Michael DOUBEZ <michael.dou... @free.frwrote:
                  Michal Nazarewicz a écrit :
                  Aman JIANG <AmanJI...@gmai l.comwrites:
                  On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.pl wrote:
                  >How about:
                  >#v+
                  >std::string toString(long value) {
                  > char buffer[100];
                  > sprintf(buffer, "%ld", value);
                  > return std::string(buf fer);
                  >}
                  >[snip]
                  >It's C++ all right.
                  thank you :)
                  > char buffer[100];
                  that "100" is a magic number.
                  Yep, its a number long enough to hold a string representation of
                  a (unsigned) long value.
                  You can use numeric_limits< >::digits10 to fit the size to you type.
                  The original poster also had a version for double.
                  numeric_limits< >::digits10 doesn't suffice there (especially for
                  "%f").
                  // add one for \0 and for additional digit
                  // add one more for sign with signed
                  char buffer [std::numeric_li mits<unsigned long>::digits10 + 2];
                  In fact, with traits, it should be possible to write a template.
                  Possible, but rather tricky. Don't forget that the format
                  specifier would have to depend on the type. You'd end up having
                  to explicitly specialize the traits for each type, with as much
                  work as if you'd just written a separate function for each type.

                  Just another reason why nobody in their right mind would want to
                  use the printf family of functions.

                  --
                  James Kanze (GABI Software) email:james.kan ze@gmail.com
                  Conseils en informatique orientée objet/
                  Beratung in objektorientier ter Datenverarbeitu ng
                  9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                  Comment

                  • Michal Nazarewicz

                    #10
                    Re: conversion between string and numerical value

                    James Kanze <james.kanze@gm ail.comwrites:
                    Possible, but rather tricky. Don't forget that the format
                    specifier would have to depend on the type. You'd end up having
                    to explicitly specialize the traits for each type, with as much
                    work as if you'd just written a separate function for each type.
                    >
                    Just another reason why nobody in their right mind would want to
                    use the printf family of functions.
                    There are plenty of people (including myself) who prefer C stdio to C++
                    streams.

                    --
                    Best regards, _ _
                    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
                    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
                    ooo +--<mina86*tlen.pl >---<jid:mina86*chr ome.pl>--ooO--(_)--Ooo--

                    Comment

                    • anon

                      #11
                      Re: conversion between string and numerical value

                      James Kanze wrote:
                      std::string
                      toString( double value )
                      {
                      char buffer[ 100 ] ;
                      std::ostrstream s ;
                      s << value << std::ends ;
                      assert( s ) ;
                      return buffer ;
                      }
                      Looks like something is missing here.
                      1) Where is buffer used?
                      2) what is std::ends?

                      Comment

                      • BobR

                        #12
                        Re: conversion between string and numerical value


                        anon <anon@no.nowrot e in message...
                        James Kanze wrote:
                        std::string
                        toString( double value )
                        {
                        char buffer[ 100 ] ;
                        std::ostrstream s ;
                        s << value << std::ends ;
                        assert( s ) ;
                        return buffer ;
                        }
                        >
                        Looks like something is missing here.
                        1) Where is buffer used?
                        In the 'return'! <G>

                        std::ostrstream s( buffer, 100 ) ; // ??
                        2) what is std::ends?
                        Manipulator: ends
                        Write `\0' (the string terminator character).

                        --
                        Bob R
                        POVrookie


                        Comment

                        • Aman JIANG

                          #13
                          Re: conversion between string and numerical value

                          On 9 20 , 8 29 , James Kanze <james.ka...@gm ail.comwrote:
                          On some machines. There's no guarantee (although it's likely to
                          be sufficient in the near future).
                          >
                          It's not necessarily large enough to hold a "%f" conversion of a
                          float, and it's not large enough to hold a "%f" conversion of a
                          double on the machines I usually work on.
                          >
                          I might add that there is no guarantee that sprintf is faster
                          than boost::lexical_ cast, although it's likely *if*
                          boost::lexical_ cast doesn't have partial specializations for
                          std::string (since in the general case, boost::lexical_ cast must
                          do two conversions, and not just one).
                          >
                          More generally, you might try:
                          >
                          std::string
                          toString( double value )
                          {
                          std::ostringstr eam s ;
                          s << value ;
                          return s.str() ;
                          }
                          >
                          or if that's too slow:
                          >
                          std::string
                          toString( double value )
                          {
                          char buffer[ 100 ] ;
                          std::ostrstream s ;
                          s << value << std::ends ;
                          assert( s ) ;
                          return buffer ;
                          }
                          >
                          (This will at least cause an assertion failure, rather than
                          undefined behavior, if the converted string requires more than
                          99 characters. You can, of course, replace the assertion with
                          any other error handling you wish.)
                          >
                          If all else fails, you can try snprintf, which is not standard
                          C++, but is standard C99, and probably available with your
                          implementation (and allows for error checking as well).
                          >
                          Also, you probably want to use the "%g" format (the default for
                          iostream), unless you know that the input is in a very limited
                          range.
                          Thank you :)

                          I think use 'stringstream' to do this work is still expensive,
                          although it must be faster than boost::lexical_ cast. We know that
                          'strstream' was "deprecated " in C++98.

                          Is there another way to do this, no stream, and no old C-style
                          functions, please ?
                          (sorry my english is not well)

                          Comment

                          • James Kanze

                            #14
                            Re: conversion between string and numerical value

                            On Sep 20, 7:35 pm, "BobR" <removeBadB...@ worldnet.att.ne twrote:
                            anon <a...@no.nowrot e in message...
                            James Kanze wrote:
                            std::string
                            toString( double value )
                            {
                            char buffer[ 100 ] ;
                            std::ostrstream s ;
                            s << value << std::ends ;
                            assert( s ) ;
                            return buffer ;
                            }
                            Looks like something is missing here.
                            1) Where is buffer used?
                            In the 'return'! <G>
                            std::ostrstream s( buffer, 100 ) ; // ??
                            Yep. That's what I meant. I've gotten so used to
                            std::ostringstr eam that I forgot. Even though that was the
                            whole point of the thing: use an on stack buffer, rather than a
                            dynamically allocated one.

                            --
                            James Kanze (GABI Software) email:james.kan ze@gmail.com
                            Conseils en informatique orientée objet/
                            Beratung in objektorientier ter Datenverarbeitu ng
                            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                            Comment

                            • Kai-Uwe Bux

                              #15
                              Re: conversion between string and numerical value

                              James Kanze wrote:
                              On Sep 20, 1:55 pm, Michal Nazarewicz <min...@tlen.pl wrote:
                              >Aman JIANG <AmanJI...@gmai l.comwrites:
                              On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.pl wrote:
                              >How about:
                              >
                              >#v+
                              >std::string toString(long value) {
                              > char buffer[100];
                              > sprintf(buffer, "%ld", value);
                              > return std::string(buf fer);
                              >}
                              >
                              >std::string toString(unsign ed long value) {
                              > char buffer[100];
                              > sprintf(buffer, "%lu", value);
                              > return std::string(buf fer);
                              >}
                              >
                              >One more:
                              >
                              >std::string toString(double value) {
                              > char buffer[100];
                              > sprintf(buffer, "%f", value);
                              > return std::string(buf fer);
                              >}
                              >long atol(std::strin g str) { return atol(str.c_str( )); }
                              >double atof(std::strin g str) { return atof(str.c_str( )); }
                              >#v-
                              >
                              >It's C++ all right.
                              >
                              thank you :)
                              > char buffer[100];
                              that "100" is a magic number.
                              >
                              >Yep, its a number long enough to hold a string representation of
                              >a (unsigned) long value.
                              >
                              On some machines. There's no guarantee (although it's likely to
                              be sufficient in the near future).
                              >
                              It's not necessarily large enough to hold a "%f" conversion of a
                              float, and it's not large enough to hold a "%f" conversion of a
                              double on the machines I usually work on.
                              >
                              I might add that there is no guarantee that sprintf is faster
                              than boost::lexical_ cast, although it's likely *if*
                              boost::lexical_ cast doesn't have partial specializations for
                              std::string (since in the general case, boost::lexical_ cast must
                              do two conversions, and not just one).
                              >
                              More generally, you might try:
                              >
                              std::string
                              toString( double value )
                              {
                              std::ostringstr eam s ;
                              s << value ;
                              return s.str() ;
                              }
                              >
                              or if that's too slow:
                              >
                              std::string
                              toString( double value )
                              {
                              char buffer[ 100 ] ;
                              std::ostrstream s ;
                              s << value << std::ends ;
                              assert( s ) ;
                              return buffer ;
                              }
                              I do not understand this version. Where is the magic that modifies the
                              variable buffer? and how are buffer and the ostrstream s related? It looks
                              as though you return an uninitialized array of char.

                              (This will at least cause an assertion failure, rather than
                              undefined behavior, if the converted string requires more than
                              99 characters. You can, of course, replace the assertion with
                              any other error handling you wish.)
                              >
                              If all else fails, you can try snprintf, which is not standard
                              C++, but is standard C99, and probably available with your
                              implementation (and allows for error checking as well).
                              >
                              Also, you probably want to use the "%g" format (the default for
                              iostream), unless you know that the input is in a very limited
                              range.

                              Best

                              Kai-Uwe Bux

                              Comment

                              Working...