Check for whole number in template function.

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

    Check for whole number in template function.

    Dear newsgroup.

    I want to write a template function which accepts either integer or
    floating point numbers.
    If a certain result is not a whole number and if the template
    parameter is an integer, it should return false, but it should work
    normally if the parameter is a float.

    To illustrate this, I attached a minimal example.

    The background:
    I have a variable (in this case "temp") holding the result of some
    calculations and representing a time in milliseconds.
    The output, however, shall be in seconds, and the function should only
    return successfully if the value can be represented in seconds
    (without any rounding).

    The code example below does all that, but I wanted to know if there is
    a better way to do it and if this code works on all systems.

    Is it possible that the "if"-clause is optimized away?
    I compiled it with gcc with the -O3 option and it still works.

    Any comments?

    cheers,
    Matthias

    =============== =============== ========

    #include <iostream>

    template <typename T>
    bool minimal(T& output)
    {
    T temp = 500; // change this value!
    if (temp / 1000 * 1000 != temp) return false;
    else output = temp / 1000;
    }

    int main()
    {
    int i;
    if (minimal(i)) std::cout << "int works (" << i << ")!\n";
    float f;
    if (minimal(f)) std::cout << "float works (" << f << ")!\n";
    }
  • Victor Bazarov

    #2
    Re: Check for whole number in template function.

    Matthias wrote:
    Dear newsgroup.
    >
    I want to write a template function which accepts either integer or
    floating point numbers.
    If a certain result is not a whole number and if the template
    parameter is an integer, it should return false, but it should work
    normally if the parameter is a float.
    Perhaps you're better off providing specialisations of your function
    template or simply two overloaded functions?
    >
    To illustrate this, I attached a minimal example.
    >
    The background:
    I have a variable (in this case "temp") holding the result of some
    calculations and representing a time in milliseconds.
    The output, however, shall be in seconds, and the function should only
    return successfully if the value can be represented in seconds
    (without any rounding).
    >
    The code example below does all that, but I wanted to know if there is
    a better way to do it and if this code works on all systems.
    >
    Is it possible that the "if"-clause is optimized away?
    I compiled it with gcc with the -O3 option and it still works.
    >
    Any comments?
    >
    cheers,
    Matthias
    >
    =============== =============== ========
    >
    #include <iostream>
    >
    template <typename T>
    bool minimal(T& output)
    {
    T temp = 500; // change this value!
    if (temp / 1000 * 1000 != temp) return false;
    else output = temp / 1000;
    }
    So, what's wrong with, say

    bool minimal(int&) { return false; }
    bool minimal(float& f) { f = 0.5; return true; }

    ?
    >
    int main()
    {
    int i;
    if (minimal(i)) std::cout << "int works (" << i << ")!\n";
    float f;
    if (minimal(f)) std::cout << "float works (" << f << ")!\n";
    }
    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • joseph  cook

      #3
      Re: Check for whole number in template function.

      On Nov 6, 8:22 pm, Matthias <Matthias.Ge... @gmail.comwrote :
      Dear newsgroup.
      >
      I want to write a template function which accepts either integer or
      floating point numbers.
      If a certain result is not a whole number and if the template
      parameter is an integer, it should return false, but it should work
      normally if the parameter is a float.
      >
      To illustrate this, I attached a minimal example.
      >
      The background:
      I have a variable (in this case "temp") holding the result of some
      calculations and representing a time in milliseconds.
      The output, however, shall be in seconds, and the function should only
      return successfully if the value can be represented in seconds
      (without any rounding).
      >
      The code example below does all that, but I wanted to know if there is
      a better way to do it and if this code works on all systems.
      >
      Is it possible that the "if"-clause is optimized away?
      I compiled it with gcc with the -O3 option and it still works.
      You could look at functions from the limits header like:

      #include <limits>
      if (numeric_limits <T>::is_integer )
      ....

      Joe Cook

      Comment

      • James Kanze

        #4
        Re: Check for whole number in template function.

        On Nov 7, 3:13 am, joseph cook <joec...@gmail. comwrote:
        On Nov 6, 8:22 pm, Matthias <Matthias.Ge... @gmail.comwrote :
        I want to write a template function which accepts either
        integer or floating point numbers.
        If a certain result is not a whole number and if the
        template parameter is an integer, it should return false,
        but it should work normally if the parameter is a float.
        To illustrate this, I attached a minimal example.
        The background:
        I have a variable (in this case "temp") holding the result
        of some calculations and representing a time in
        milliseconds. The output, however, shall be in seconds, and
        the function should only return successfully if the value
        can be represented in seconds (without any rounding).
        The code example below does all that, but I wanted to know
        if there is a better way to do it and if this code works on
        all systems.
        Is it possible that the "if"-clause is optimized away? I
        compiled it with gcc with the -O3 option and it still works.
        You could look at functions from the limits header like:
        #include <limits>
        if (numeric_limits <T>::is_integer )
        ....
        Note that numeric_limits< T>::is_integer is NOT a function, and
        that the standard requires it to be usable as an integral
        constant expression. So you can specialize on it, and write
        something like:

        template< bool Is struct Discriminater {} ;

        template< typename T >
        bool
        functionHelper( T in, Discriminater< true )
        {
        // handle integer case...
        }

        template< typename T >
        bool
        functionHelper( T in, Discriminater< false )
        {
        // handle floating point...
        }

        template< typename T >
        bool
        function( T in )
        {
        // ...
        functionHelper(
        in, Discriminater< std::numeric_li mits< T >::is_integer
        >() ) ;
        // ...
        }

        (But depending on what he's doing, a simple runtime check might
        be sufficient, and is a lot simpler.)

        --
        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

        • Matthias

          #5
          Re: Check for whole number in template function.

          Hi again.

          Thanks for the responses!

          On Nov 7, 10:31 am, James Kanze <james.ka...@gm ail.comwrote:
          On Nov 7, 3:13 am, joseph  cook <joec...@gmail. comwrote:
          On Nov 6, 8:22 pm, Matthias <Matthias.Ge... @gmail.comwrote :
          I have a variable (in this case "temp") holding the result
          of some calculations and representing a time in
          milliseconds.  The output, however, shall be in seconds, and
          the function should only return successfully if the value
          can be represented in seconds (without any rounding).
          The code example below does all that, but I wanted to know
          if there is a better way to do it and if this code works on
          all systems.
          [...]
          if (temp / 1000 * 1000 != temp) return false;
          else output = temp / 1000;
          [...]
          Is it possible that the "if"-clause is optimized away?  I
          compiled it with gcc with the -O3 option and it still works.
          You could look at functions from the limits header like:
          #include <limits>
          if (numeric_limits <T>::is_integer )
           ....
          >
          [... code example ...]
          >
          (But depending on what he's doing, a simple runtime check might
          be sufficient, and is a lot simpler.)
          Yes, exactly. The is_integer solution might work, but in my case it's
          overkill.
          I would prefer a simple runtime check.

          Let me add some details about the function I'm trying to write:
          In this function an input string is parsed which contains a time. This
          time is normally in seconds, but a suffix can specify if it should be
          hours, minutes, seconds or milliseconds.
          Now if the output type is "int", I only want it to return successfully
          if the result represents the input without loss of information.
          Basically, if the input is "5000ms", the resulting integer should be
          5, but if its "500ms" the function should return an error. The "float"-
          version, however, should simply return 0.5.
          I guess a simple template specialization doesn't work in this case
          because of the dependence on the input string.

          Does the code I suggested in my inital posting work in all cases as
          I'm expecting?
          Or do you know a more suitable runtime check?

          I think I could also rephrase my problem into:
          If a given number having a given type is divided by 1000, does it
          loose any information?

          cheers,
          Matthias

          Comment

          • Hendrik Schober

            #6
            Re: Check for whole number in template function.

            Matthias wrote:
            On Nov 7, 10:31 am, James Kanze <james.ka...@gm ail.comwrote:
            [... code example ...]
            >(But depending on what he's doing, a simple runtime check might
            >be sufficient, and is a lot simpler.)
            >
            Yes, exactly. The is_integer solution might work, but in my case it's
            overkill.
            I would prefer a simple runtime check.
            I'm not sure what "simple runtime check" is supposed to mean.
            Does it mean you want a simple check done at run-time or does
            it mean run-time checks are (supposed to be) simpler?
            Let me add some details about the function I'm trying to write:
            In this function an input string is parsed which contains a time. This
            time is normally in seconds, but a suffix can specify if it should be
            hours, minutes, seconds or milliseconds.
            Now if the output type is "int", I only want it to return successfully
            if the result represents the input without loss of information.
            Basically, if the input is "5000ms", the resulting integer should be
            5, but if its "500ms" the function should return an error. The "float"-
            version, however, should simply return 0.5.
            I guess a simple template specialization doesn't work in this case
            because of the dependence on the input string.
            There's two dependencies here, from my POV: the one on the
            string, which indeed is a run-time one, and the one on the
            data type, which is known at compile-time.
            I see no problem in checking the type dependency at runtime.
            The string parsing has to be done at run-time, but what's to
            be done with the result when the data type is an integer
            could well be decided at compile-time.
            [...]
            Matthias
            Schobi

            Comment

            • Matthias

              #7
              Re: Check for whole number in template function.

              Hi Hendrik, hi Group.

              Thanks for the answer, sorry that it took me so long to respond ...

              On 11 Nov., 11:25, Hendrik Schober <spamt...@gmx.d ewrote:
              Matthias wrote:
              On Nov 7, 10:31 am, James Kanze <james.ka...@gm ail.comwrote:
              [... code example ...]
              (But depending on what he's doing, a simple runtime check might
              be sufficient, and is a lot simpler.)
              Yes, exactly. The is_integer solution might work, but in my case it's
              overkill.
              I would prefer a simple runtime check.
              >
                I'm not sure what "simple runtime check" is supposed to mean.
                Does it mean you want a simple check done at run-time or does
                it mean run-time checks are (supposed to be) simpler?
              I didn't really think so much about the use of the word "simple", but
              I guess I meant simple in the sense that it's easy to implement and
              easy to read and understand.
              I think in this respect my initial proposal is "simpler", but I still
              don't know if I can use it safely.
                There's two dependencies here, from my POV: the one on the
                string, which indeed is a run-time one, and the one on the
                data type, which is known at compile-time.
                I see no problem in checking the type dependency at runtime.
                The string parsing has to be done at run-time, but what's to
                be done with the result when the data type is an integer
                could well be decided at compile-time.
              But everything depends on the input string AND on the data type.
              If the data type is an integer, it should only return successfully if
              the given number is a multiple of 1000.

              Now the question is still: How do I check this reliably?
              And it would be nice if it's still "simple" ...
              Would be nice if that could be done in only very few lines of code.

              Can anyone tell me if my initial proposal is good or bad?
              Here it is again (by the way, I forgot the "return true;" in my
              original posting):

              if (temp / 1000 * 1000 != temp) return false;
              else output = temp / 1000;
              return true;

              cheers,
              Matthias

              Comment

              • Victor Bazarov

                #8
                Re: Check for whole number in template function.

                Matthias wrote:
                Hi Hendrik, hi Group.
                >
                Thanks for the answer, sorry that it took me so long to respond ...
                >
                On 11 Nov., 11:25, Hendrik Schober <spamt...@gmx.d ewrote:
                >Matthias wrote:
                >>On Nov 7, 10:31 am, James Kanze <james.ka...@gm ail.comwrote:
                >>[... code example ...]
                >>>(But depending on what he's doing, a simple runtime check might
                >>>be sufficient, and is a lot simpler.)
                >>Yes, exactly. The is_integer solution might work, but in my case it's
                >>overkill.
                >>I would prefer a simple runtime check.
                > I'm not sure what "simple runtime check" is supposed to mean.
                > Does it mean you want a simple check done at run-time or does
                > it mean run-time checks are (supposed to be) simpler?
                >
                I didn't really think so much about the use of the word "simple", but
                I guess I meant simple in the sense that it's easy to implement and
                easy to read and understand.
                I think in this respect my initial proposal is "simpler", but I still
                don't know if I can use it safely.
                >
                > There's two dependencies here, from my POV: the one on the
                > string, which indeed is a run-time one, and the one on the
                > data type, which is known at compile-time.
                > I see no problem in checking the type dependency at runtime.
                > The string parsing has to be done at run-time, but what's to
                > be done with the result when the data type is an integer
                > could well be decided at compile-time.
                >
                But everything depends on the input string AND on the data type.
                If the data type is an integer, it should only return successfully if
                the given number is a multiple of 1000.
                >
                Now the question is still: How do I check this reliably?
                And it would be nice if it's still "simple" ...
                Would be nice if that could be done in only very few lines of code.
                >
                Can anyone tell me if my initial proposal is good or bad?
                Here it is again (by the way, I forgot the "return true;" in my
                original posting):
                >
                if (temp / 1000 * 1000 != temp) return false;
                else output = temp / 1000;
                return true;
                So, let me get this straight. When you parse your string, the number
                that you input can (internally) be of two different types? How do you
                make your determination? Presence of the decimal separator? So, if the
                input contains "1.5H", it's floating point, and if it's "1M", it's an
                integer? Why? What if your algorithm always inputs a floating point
                and if there is a suffix, converts the number to seconds and only then
                checks if it has a fractional part? You still can do it, can't you?
                What is the range of times you're hoping to process? What's the maximum
                time? What's the minimum time? Even 1000H is only 3.6e6 seconds and
                can be determined to have (or not to have) a fraction if converted to an
                integer ('unsigned long' should suffice)...

                I believe you're trying to solve a wrong problem here.

                Also, have you read the FAQ section 35 (templates)? Also, did you see
                my response to your original post?

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

                Comment

                • Matthias

                  #9
                  Re: Check for whole number in template function.

                  Hello Victor.

                  Thanks very much for your response.
                  It made me think that maybe templates aren't that good in this
                  case ...
                  So, let me get this straight.  When you parse your string, the number
                  that you input can (internally) be of two different types?  How do you
                  make your determination?  Presence of the decimal separator?  So, if the
                  input contains "1.5H", it's floating point, and if it's "1M", it's an
                  integer?  Why?  What if your algorithm always inputs a floating point
                  and if there is a suffix, converts the number to seconds and only then
                  checks if it has a fractional part?  You still can do it, can't you?
                  The input string can be either just a number (which would mean
                  seconds), or a number with one of the suffixes "h", "min", "s" or
                  "ms".
                  The number can be positive or negative and it may or may not have a
                  decimal point.

                  And yes, now I see that I would first have to read a floating point
                  value anyway, even if the template type is an integer.

                  I just searched for how to check for the fractional part and found the
                  modf() function which I didn't know before!
                  Are you speaking about this one?

                  I think theoretically I could combine this with the is_integer
                  solution suggested by James and that would solve my problem.
                  But this gets far more complex than what I expected before, so maybe I
                  should go the easy way doing it without templates and just implement
                  it for one single type, e.g. float.
                  What is the range of times you're hoping to process?  What's the maximum
                  time?  What's the minimum time?  Even 1000H is only 3.6e6 seconds and
                  can be determined to have (or not to have) a fraction if converted to an
                  integer ('unsigned long' should suffice)...
                  I was thinking about times from several milliseconds to a few days.
                  I believe you're trying to solve a wrong problem here.
                  Yeah, I think you are right.

                  The reason why I came up with that problem is that I didn't want to
                  decide if I should implement it in float or double.
                  For my current use I guess float is sufficient, but I wanted to write
                  it in a way that I can use it for other applications in the future.
                  So I decided to try it with a template.
                  Then I had the problem that the function would also work for integers
                  but it would sometimes produce the wrong result ("1600ms" would become
                  1 second).
                  Also, have you read the FAQ section 35 (templates)?  Also, did you see
                  my response to your original post?
                  Yes, I've read the FAQ section.
                  And of course I've read your first response, sorry that I didn't reply
                  directly to that, but I wrote in another response that because of the
                  dependence on the input string template specialization (alone)
                  wouldn't help in my case (If I understood that correctly).

                  cheers,
                  Matthias

                  Comment

                  • Victor Bazarov

                    #10
                    Re: Check for whole number in template function.

                    Matthias wrote:
                    Hello Victor.
                    >
                    Thanks very much for your response.
                    It made me think that maybe templates aren't that good in this
                    case ...
                    >
                    >So, let me get this straight. When you parse your string, the number
                    >that you input can (internally) be of two different types? How do you
                    >make your determination? Presence of the decimal separator? So, if the
                    >input contains "1.5H", it's floating point, and if it's "1M", it's an
                    >integer? Why? What if your algorithm always inputs a floating point
                    >and if there is a suffix, converts the number to seconds and only then
                    >checks if it has a fractional part? You still can do it, can't you?
                    >
                    The input string can be either just a number (which would mean
                    seconds), or a number with one of the suffixes "h", "min", "s" or
                    "ms".
                    The number can be positive or negative and it may or may not have a
                    decimal point.
                    >
                    And yes, now I see that I would first have to read a floating point
                    value anyway, even if the template type is an integer.
                    >
                    I just searched for how to check for the fractional part and found the
                    modf() function which I didn't know before!
                    Are you speaking about this one?
                    Sure.
                    I think theoretically I could combine this with the is_integer
                    solution suggested by James and that would solve my problem.
                    You don't need to. Just use double and be done with it.
                    But this gets far more complex than what I expected before, so maybe I
                    should go the easy way doing it without templates and just implement
                    it for one single type, e.g. float.
                    'double'. See below.
                    >What is the range of times you're hoping to process? What's the maximum
                    >time? What's the minimum time? Even 1000H is only 3.6e6 seconds and
                    >can be determined to have (or not to have) a fraction if converted to an
                    >integer ('unsigned long' should suffice)...
                    >
                    I was thinking about times from several milliseconds to a few days.
                    With the millisecond suffix, how would you specify several days? There
                    are 86400000 milliseconds in a day, which gives you a range of more than
                    10 thousand *years* you can safely represent in a *double* (with ~15
                    decimal digits of precision) using the millisecond suffix. In a *float*
                    with guaranteed 6 digits you can only represent 0.01 day with the
                    millisecond suffix. That seems a good argument toward using 'double'
                    for your number representation. And, yes, you can use 'modf'. If you
                    try to convert to 'unsigned long', you're limited to 49 days of
                    representation with the millisecond suffix, but you will be able to
                    determine if there is fractional part: convert your value to unsigned
                    long, convert the result back to double, and compare the two doubles.
                    [..]
                    V
                    --
                    Please remove capital 'A's when replying by e-mail
                    I do not respond to top-posted replies, please don't ask

                    Comment

                    • Matthias

                      #11
                      Re: Check for whole number in template function.

                      Hi Victor.

                      Thank you for your very helpful reply!

                      I'll implement it with double as you suggested and I will forget about
                      all this template Mumbo Jumbo (for now ...).

                      Thanks also to the others who responded, I learned quite a lot from
                      you!

                      cheers,
                      Matthias

                      On 14 Nov., 14:57, Victor Bazarov <v.Abaza...@com Acast.netwrote:
                      Matthias wrote:
                      Hello Victor.
                      >
                      Thanks very much for your response.
                      It made me think that maybe templates aren't that good in this
                      case ...
                      >
                      So, let me get this straight.  When you parse your string, the number
                      that you input can (internally) be of two different types?  How do you
                      make your determination?  Presence of the decimal separator?  So, if the
                      input contains "1.5H", it's floating point, and if it's "1M", it's an
                      integer?  Why?  What if your algorithm always inputs a floating point
                      and if there is a suffix, converts the number to seconds and only then
                      checks if it has a fractional part?  You still can do it, can't you?
                      >
                      The input string can be either just a number (which would mean
                      seconds), or a number with one of the suffixes "h", "min", "s" or
                      "ms".
                      The number can be positive or negative and it may or may not have a
                      decimal point.
                      >
                      And yes, now I see that I would first have to read a floating point
                      value anyway, even if the template type is an integer.
                      >
                      I just searched for how to check for the fractional part and found the
                      modf() function which I didn't know before!
                      Are you speaking about this one?
                      >
                      Sure.
                      >
                      I think theoretically I could combine this with the is_integer
                      solution suggested by James and that would solve my problem.
                      >
                      You don't need to.  Just use double and be done with it.
                      >
                      But this gets far more complex than what I expected before, so maybe I
                      should go the easy way doing it without templates and just implement
                      it for one single type, e.g. float.
                      >
                      'double'.  See below.
                      >
                      What is the range of times you're hoping to process?  What's the maximum
                      time?  What's the minimum time?  Even 1000H is only 3.6e6 seconds and
                      can be determined to have (or not to have) a fraction if converted to an
                      integer ('unsigned long' should suffice)...
                      >
                      I was thinking about times from several milliseconds to a few days.
                      >
                      With the millisecond suffix, how would you specify several days?  There
                      are 86400000 milliseconds in a day, which gives you a range of more than
                      10 thousand *years* you can safely represent in a *double* (with ~15
                      decimal digits of precision) using the millisecond suffix.  In a *float*
                      with guaranteed 6 digits you can only represent 0.01 day with the
                      millisecond suffix.  That seems a good argument toward using 'double'
                      for your number representation.  And, yes, you can use 'modf'.  If you
                      try to convert to 'unsigned long', you're limited to 49 days of
                      representation with the millisecond suffix, but you will be able to
                      determine if there is fractional part: convert your value to unsigned
                      long, convert the result back to double, and compare the two doubles.
                      >
                      [..]
                      >
                      V
                      --
                      Please remove capital 'A's when replying by e-mail
                      I do not respond to top-posted replies, please don't ask

                      Comment

                      Working...