for loop does not work as it should

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

    #1

    for loop does not work as it should

    Can someone run the code below and tell me why it never reaches 0.06?
    I am really puzzled..... or just going crazy?

    Dim i As Double
    For i = 0.01 To 0.05 Step 0.01
    Debug.WriteLine (i)
    Next
    Debug.WriteLine ("*******max0.0 5************")

    For i = 0.01 To 0.06 Step 0.01
    Debug.WriteLine (i)
    Next
    Debug.WriteLine ("*******max0.0 6************")

    For i = 0.01 To 0.07 Step 0.01
    Debug.WriteLine (i)
    Next
    Debug.WriteLine ("*******max0.0 7************")

    I get the output below:

    0.01
    0.02
    0.03
    0.04
    0.05
    *******max0.05* ***********
    0.01
    0.02
    0.03
    0.04
    0.05
    *******max0.06* ***********
    0.01
    0.02
    0.03
    0.04
    0.05
    0.06
    0.07
    *******max0.07* ***********

  • =?ISO-8859-1?Q?G=F6ran_Andersson?=

    #2
    Re: for loop does not work as it should

    UnkleVo wrote:
    Can someone run the code below and tell me why it never reaches 0.06?
    I am really puzzled..... or just going crazy?
    >
    Dim i As Double
    For i = 0.01 To 0.05 Step 0.01
    Debug.WriteLine (i)
    Next
    Debug.WriteLine ("*******max0.0 5************")
    >
    For i = 0.01 To 0.06 Step 0.01
    Debug.WriteLine (i)
    Next
    Debug.WriteLine ("*******max0.0 6************")
    >
    For i = 0.01 To 0.07 Step 0.01
    Debug.WriteLine (i)
    Next
    Debug.WriteLine ("*******max0.0 7************")
    >
    I get the output below:
    >
    0.01
    0.02
    0.03
    0.04
    0.05
    *******max0.05* ***********
    0.01
    0.02
    0.03
    0.04
    0.05
    *******max0.06* ***********
    0.01
    0.02
    0.03
    0.04
    0.05
    0.06
    0.07
    *******max0.07* ***********
    >
    You can't rely on an exact value when you are using a floating point
    number. Very few numbers can be expressed exactly as a floating point
    number, most numbers are expressed as a number that is slightly off.

    When you think that you are adding exactly 0.01 to the loop counter, you
    are actually adding something that is very close to 0.01 but not
    exactly. Each time you add to the counter, the result will be rounded to
    the closest representation that can be stored in a double, and when you
    get to the sixth step in the loop, the result will be slightly more than
    0.06, which results in the loop ending.

    It's not the middle loop that is wrong. You were just lucky that the
    other two loops did not do the same.

    --
    Göran Andersson
    _____
    Göran Anderssons privata hemsida.

    Comment

    • SAL

      #3
      Re: for loop does not work as it should

      That's right. Good one.
      What you could do though is change your loop to a while loop, set your
      starting value before you enter the loop and have the loop say:

      While i < .07
      ' do something
      i += .01
      Wend

      That should get you the results you are looking for. Or, you could do it in
      C# as follows

      for i = .01; i < .07, i += .01
      {
      // do something
      }

      "Göran Andersson" <guffa@guffa.co mwrote in message
      news:%23ZzEHbgW HHA.4188@TK2MSF TNGP06.phx.gbl. ..
      UnkleVo wrote:
      >Can someone run the code below and tell me why it never reaches 0.06?
      >I am really puzzled..... or just going crazy?
      >>
      > Dim i As Double
      > For i = 0.01 To 0.05 Step 0.01
      > Debug.WriteLine (i)
      > Next
      > Debug.WriteLine ("*******max0.0 5************")
      >>
      > For i = 0.01 To 0.06 Step 0.01
      > Debug.WriteLine (i)
      > Next
      > Debug.WriteLine ("*******max0.0 6************")
      >>
      > For i = 0.01 To 0.07 Step 0.01
      > Debug.WriteLine (i)
      > Next
      > Debug.WriteLine ("*******max0.0 7************")
      >>
      >I get the output below:
      >>
      >0.01
      >0.02
      >0.03
      >0.04
      >0.05
      >*******max0.05 ************
      >0.01
      >0.02
      >0.03
      >0.04
      >0.05
      >*******max0.06 ************
      >0.01
      >0.02
      >0.03
      >0.04
      >0.05
      >0.06
      >0.07
      >*******max0.07 ************
      >>
      >
      You can't rely on an exact value when you are using a floating point
      number. Very few numbers can be expressed exactly as a floating point
      number, most numbers are expressed as a number that is slightly off.
      >
      When you think that you are adding exactly 0.01 to the loop counter, you
      are actually adding something that is very close to 0.01 but not exactly.
      Each time you add to the counter, the result will be rounded to the
      closest representation that can be stored in a double, and when you get to
      the sixth step in the loop, the result will be slightly more than 0.06,
      which results in the loop ending.
      >
      It's not the middle loop that is wrong. You were just lucky that the other
      two loops did not do the same.
      >
      --
      Göran Andersson
      _____
      http://www.guffa.com

      Comment

      • =?ISO-8859-1?Q?G=F6ran_Andersson?=

        #4
        Re: for loop does not work as it should

        Actually, it doesn't matter how you do the loop, as long as you expect
        floating point values to be exact, as you do in your code. You will
        experience the same kind of unreliability, only with different results
        for any given number as you are using the < operator instead of the <=
        opreator that is used by the For loop.

        A reliable way of looping using a floating point counter is to put the
        end condition right between the number that should be included and the
        number that shouldn't.

        To loop from 0.01 to 0.05, the value 0.05 should be included but not
        0.06. To make sure that this happens, put the end condition between 0.05
        and 0.06:

        For i = 0.01 to 0.055 Step 0.01

        SAL wrote:
        That's right. Good one.
        What you could do though is change your loop to a while loop, set your
        starting value before you enter the loop and have the loop say:
        >
        While i < .07
        ' do something
        i += .01
        Wend
        >
        That should get you the results you are looking for. Or, you could do it in
        C# as follows
        >
        for i = .01; i < .07, i += .01
        {
        // do something
        }
        >
        "Göran Andersson" <guffa@guffa.co mwrote in message
        news:%23ZzEHbgW HHA.4188@TK2MSF TNGP06.phx.gbl. ..
        >UnkleVo wrote:
        >>Can someone run the code below and tell me why it never reaches 0.06?
        >>I am really puzzled..... or just going crazy?
        >>>
        >> Dim i As Double
        >> For i = 0.01 To 0.05 Step 0.01
        >> Debug.WriteLine (i)
        >> Next
        >> Debug.WriteLine ("*******max0.0 5************")
        >>>
        >> For i = 0.01 To 0.06 Step 0.01
        >> Debug.WriteLine (i)
        >> Next
        >> Debug.WriteLine ("*******max0.0 6************")
        >>>
        >> For i = 0.01 To 0.07 Step 0.01
        >> Debug.WriteLine (i)
        >> Next
        >> Debug.WriteLine ("*******max0.0 7************")
        >>>
        >>I get the output below:
        >>>
        >>0.01
        >>0.02
        >>0.03
        >>0.04
        >>0.05
        >>*******max0.0 5************
        >>0.01
        >>0.02
        >>0.03
        >>0.04
        >>0.05
        >>*******max0.0 6************
        >>0.01
        >>0.02
        >>0.03
        >>0.04
        >>0.05
        >>0.06
        >>0.07
        >>*******max0.0 7************
        >>>
        >You can't rely on an exact value when you are using a floating point
        >number. Very few numbers can be expressed exactly as a floating point
        >number, most numbers are expressed as a number that is slightly off.
        >>
        >When you think that you are adding exactly 0.01 to the loop counter, you
        >are actually adding something that is very close to 0.01 but not exactly.
        >Each time you add to the counter, the result will be rounded to the
        >closest representation that can be stored in a double, and when you get to
        >the sixth step in the loop, the result will be slightly more than 0.06,
        >which results in the loop ending.
        >>
        >It's not the middle loop that is wrong. You were just lucky that the other
        >two loops did not do the same.
        >>
        >--
        >Göran Andersson
        >_____
        >http://www.guffa.com
        >
        >

        --
        Göran Andersson
        _____
        Göran Anderssons privata hemsida.

        Comment

        • Herfried K. Wagner [MVP]

          #5
          Re: for loop does not work as it should

          "SAL" <SAL_@NoNo.coms chrieb:
          What you could do though is change your loop to a while loop, set your
          starting value before you enter the loop and have the loop say:
          >
          While i < .07
          ' do something
          i += .01
          Wend
          Note that 'Wend' has been replaced by 'End While' in VB.NET for some unknown
          reasons.

          --
          M S Herfried K. Wagner
          M V P <URL:http://dotnet.mvps.org/>
          V B <URL:http://dotnet.mvps.org/dotnet/faqs/>

          Comment

          • Michael C

            #6
            Re: for loop does not work as it should

            "Göran Andersson" <guffa@guffa.co mwrote in message
            news:en08D%23gW HHA.4632@TK2MSF TNGP04.phx.gbl. ..
            To loop from 0.01 to 0.05, the value 0.05 should be included but not 0.06.
            To make sure that this happens, put the end condition between 0.05 and
            0.06:
            >
            For i = 0.01 to 0.055 Step 0.01
            Better to just use
            for j = 1 to 5
            i = i + 0.01
            'OR
            i = j * 0.01
            next

            I actually think the second would be better as it reduces rounding errors
            slightly, although I suspect it would be insignificant in this particular
            case.

            Michael


            Comment

            • Jay B. Harlow [MVP - Outlook]

              #7
              Re: for loop does not work as it should

              UnkleVo,
              In addition to the other comments, consider using Decimal instead of Double
              or Single.

              As Decimal is a base 10 floating point number, where as Single & Double are
              base 2 floating point numbers. Base 10 floating point numbers (such as
              Decimal) can exactly represent all base 10 floating point #, where as base 2
              floating point numbers (such as Double & Single) may causing rounding
              problems for various base 10 floating point numbers

              Something like:

              Dim i As Decimal
              For i = 0.01D To 0.05D Step 0.01D
              Debug.WriteLine (i)
              Next
              Debug.WriteLine ("*******max0.0 5************")

              For i = 0.01D To 0.06D Step 0.01D
              Debug.WriteLine (i)
              Next
              Debug.WriteLine ("*******max0.0 6************")

              For i = 0.01D To 0.07D Step 0.01D
              Debug.WriteLine (i)
              Next
              Debug.WriteLine ("*******max0.0 7************")

              NOTE: 0.01D is a Decimal literal, where as 0.01 is a Double literal & 0.01F
              is a Single literal.

              --
              Hope this helps
              Jay B. Harlow [MVP - Outlook]
              ..NET Application Architect, Enthusiast, & Evangelist
              T.S. Bradley - http://www.tsbradley.net


              "UnkleVo" <unklevo@gmail. comwrote in message
              news:1172534639 .654870.248830@ s48g2000cws.goo glegroups.com.. .
              Can someone run the code below and tell me why it never reaches 0.06?
              I am really puzzled..... or just going crazy?
              >
              Dim i As Double
              For i = 0.01 To 0.05 Step 0.01
              Debug.WriteLine (i)
              Next
              Debug.WriteLine ("*******max0.0 5************")
              >
              For i = 0.01 To 0.06 Step 0.01
              Debug.WriteLine (i)
              Next
              Debug.WriteLine ("*******max0.0 6************")
              >
              For i = 0.01 To 0.07 Step 0.01
              Debug.WriteLine (i)
              Next
              Debug.WriteLine ("*******max0.0 7************")
              >
              I get the output below:
              >
              0.01
              0.02
              0.03
              0.04
              0.05
              *******max0.05* ***********
              0.01
              0.02
              0.03
              0.04
              0.05
              *******max0.06* ***********
              0.01
              0.02
              0.03
              0.04
              0.05
              0.06
              0.07
              *******max0.07* ***********
              >

              Comment

              • UnkleVo

                #8
                Re: for loop does not work as it should

                On Feb 26, 9:33 pm, "Jay B. Harlow [MVP - Outlook]"
                <Jay_Harlow_... @tsbradley.netw rote:
                UnkleVo,
                In addition to the other comments, consider using Decimal instead of Double
                or Single.
                >
                As Decimal is a base 10 floating point number, where as Single & Double are
                base 2 floating point numbers. Base 10 floating point numbers (such as
                Decimal) can exactly represent all base 10 floating point #, where as base 2
                floating point numbers (such as Double & Single) may causing rounding
                problems for various base 10 floating point numbers
                >
                Something like:
                >
                Dim i As Decimal
                For i = 0.01D To 0.05D Step 0.01D
                Debug.WriteLine (i)
                Next
                Debug.WriteLine ("*******max0.0 5************")
                >
                For i = 0.01D To 0.06D Step 0.01D
                Debug.WriteLine (i)
                Next
                Debug.WriteLine ("*******max0.0 6************")
                >
                For i = 0.01D To 0.07D Step 0.01D
                Debug.WriteLine (i)
                Next
                Debug.WriteLine ("*******max0.0 7************")
                >
                NOTE: 0.01D is a Decimal literal, where as 0.01 is a Double literal & 0.01F
                is a Single literal.
                >
                --
                Hope this helps
                Jay B. Harlow [MVP - Outlook]
                .NET Application Architect, Enthusiast, & Evangelist
                T.S. Bradley -http://www.tsbradley.n et
                >
                "UnkleVo" <unkl...@gmail. comwrote in message
                >
                news:1172534639 .654870.248830@ s48g2000cws.goo glegroups.com.. .
                >
                >
                >
                Can someone run the code below and tell me why it never reaches 0.06?
                I am really puzzled..... or just going crazy?
                >
                Dim i As Double
                For i = 0.01 To 0.05 Step 0.01
                Debug.WriteLine (i)
                Next
                Debug.WriteLine ("*******max0.0 5************")
                >
                For i = 0.01 To 0.06 Step 0.01
                Debug.WriteLine (i)
                Next
                Debug.WriteLine ("*******max0.0 6************")
                >
                For i = 0.01 To 0.07 Step 0.01
                Debug.WriteLine (i)
                Next
                Debug.WriteLine ("*******max0.0 7************")
                >
                I get the output below:
                >
                0.01
                0.02
                0.03
                0.04
                0.05
                *******max0.05* ***********
                0.01
                0.02
                0.03
                0.04
                0.05
                *******max0.06* ***********
                0.01
                0.02
                0.03
                0.04
                0.05
                0.06
                0.07
                *******max0.07* ***********- Hide quoted text -
                >
                - Show quoted text -
                Thank you very much, everyone.

                Comment

                Working...