[2 days left] Whatâ€™s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
Solved

# For Next loop not counting correctly

Posted on 2008-10-01
Medium Priority
226 Views
Hi Experts,

When I execute the attached code the loop does not count from 1 to 2 in the expected way.

1
1.1
...
1.9
2.0

Instead it doe something like this

1
1.1
1.2000000000000002
...
1.9000000000000008
(never reaches 2)

I am sure it is because binary can not store the number 0.1 accurately so what is the accepted way to count this loop.

``````For LoopCount As Double = 1 To 2 Step 0.1
Next
``````
0
Question by:DColin
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 5
• 5
• 2
• +1

LVL 11

Expert Comment

ID: 22617197
Your double is being cast to 'Object' in the add() method, which is causing 'widening' of your number. Assert the Double to Decimal at the last second to preserve the narrowing during the cast to object.
Try:
0

LVL 86

Expert Comment

ID: 22617309
The ToString() method is being implicitly called on the resulting decimal in ladarling's above code:

You could just call it directly like this:

For LoopCount As Double = 1 To 2 Step 0.1
Next

0

LVL 37

Expert Comment

ID: 22617594
Another option is to use FormatNumber which also returns a string, but there are a lot of options as far as how to...well...format the number....

Also, to have 2.0 in the list, you'd actually have to step up to 2.1....

For LoopCount As Double = 1 To 2.1 Step 0.1
Next
0

LVL 86

Expert Comment

ID: 22617683
Or go from 10 to 20 instead and display it with the formatting in ToString() itself:

For LoopCount As Integer = 10 To 20
Next
0

LVL 11

Expert Comment

ID: 22617692
Idle_Mind said: The ToString() method is being implicitly called on the resulting decimal in ladarling's above code.
Why makes you say that? Casting to the 'Object' type does not imply a conversion of any kind, since all types widen to object. And conversion from double to decimal types is explicit and narrowing within the numeric types, and also does not imply a string conversion.
http://msdn.microsoft.com/en-us/library/k1e94s7e(VS.80).aspx

ListBox items are type Object, so I am not confused by your assertion...
0

LVL 11

Expert Comment

ID: 22617701
And by not confused, I me 'confused", lol. Confusing, eh?
0

LVL 86

Expert Comment

ID: 22618169
The act of converting to decimal with CDec() doesn't call ToString()...on that you are correct.  =)

It is the ListBox itself that is calling ToString() on your Decimal object when it displays it on the GUI for you.

"When an object is added to the collection, the ListBox first checks to see if the DisplayMember property of the ListControl class has the name of a member from the object specified to reference when obtaining the item text. If the DisplayMember property does not have a member specified, the ListBox then calls the ToString method of the object to obtain the text to display in the list."

It is the ToString() call (that is automatically being done for you) that actually causes the proper display of the value...not the CDec() conversion.

This is evidenced by the snippet I posted:

For LoopCount As Double = 1 To 2 Step 0.1
Next

It resulted in the output below.  Note that NO conversion to Decimal was necessary at all...  =)

ListBox.jpg
0

LVL 11

Accepted Solution

ID: 22618938
Idle_Mind: It resulted in the output below.  Note that NO conversion to Decimal was necessary at all...  =)
Everything you posted makes perfect sense, I like it, except that if the ListBox is intrinsically calling the objects ToString() method, why is the author seeing this problem (and thus posting the question =-) on Double type variables?
So.. there seems to be something else going on with the listbox control. Any idea what it is, Idle. If you know the answer, dont tell me, I will post it for points :-)
-----------------------------------------------
I would point out to the author, by the way, that if you use a Decimal for LoopCount in the first place, all of our discussion here is moot. It works like a champ (and even actually displays 2.0). Right now I just want to pick Idls' brain on this.

0

LVL 86

Expert Comment

ID: 22619588
A perplexing problem...    *** knocks head on table ***

The ListBox.Items.Add() method expects Objects...thus we get a widening conversion on the Double to Object when it is stored in the ListBox.

It is still a Double though as the code below shows.

(Immediate Window Output)
Double : 1
Double : 1.1
Double : 1.2
Double : 1.3
Double : 1.4
Double : 1.5
Double : 1.6
Double : 1.7
Double : 1.8
Double : 1.9

But the ListBox shows it differently so as you said, "...there seems to be something else going on with the listbox control.".

To be honest, I really don't know why the ListBox's ToString() call results in different output than calling ToString() directly on the Double...or even iterating the Items() collection manually calling ToString() on each item.

I tried many combinations, converting to Object and then back to Double...I even tried displaying the values using ToString() with System.Globalization.CultureInfo.CurrentCulture and System.Globalization.CultureInfo.InvariantCulture but still couldn't reproduce the ListBoxes output.

I did find that setting the ListBox.FormatString() property to "N1" results in the desired output...not really an answer to the underlying question...just found it interesting.

So please enlighten us with a TECHNICAL answer on why the ListBox output is different.

I love learning new things.  ;)

``````Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For LoopCount As Double = 1 To 2 Step 0.1
Next
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For Each O As Object In ListBox1.Items
Debug.Print(TypeName(O) & " : " & O)
Next
End Sub

End Class
``````
ListBox.jpg
0

Author Comment

ID: 22620950
Hi Experts,

My problem is not with the list box display but the fact that this loop will not count to 2. I thought this is because binary can not store the number 0.1 so the loop does not count
1
1.1
1.2
...
1.9
2.0
But instead counts as closely to binary as the double's precision will allow. This means that the last two counts should be.
1.9
2.0
But due to the precision limitations of binary are actually.
1.900000000000008
2.000000000000009
And therefore the loop count will not go past 2 and so halts at 1.9000000000008. If this is the case how do I get around this problem using the accepted methods. VB.Net does not have a Binary Coded Decimal number type.
0

LVL 86

Expert Comment

ID: 22621049
In ladarlings last comment he stated:

"I would point out to the author, by the way, that if you use a Decimal for LoopCount in the first place, all of our discussion here is moot. It works like a champ (and even actually displays 2.0)."

So change your variable from Double to Decimal.
0

Author Comment

ID: 22621277
Thank you Idle Mind I missed ladarling's Decimal advice. It would seem VB.Net has a BCD data type after all.
0

LVL 11

Expert Comment

ID: 22624242
Idle: So please enlighten us with a TECHNICAL answer on why the ListBox output is different.

Chris: I have no Idea! I was hoping you would...lol. I did the same kind of thing you did, experimenting with debug output, etc, and could not figure it out. My *theory* is that the Listbox's double>object conversion operator is busted. I guess I could start digging through the ListBox code with the MSIL disassembler, but that sounds like tedious, tedious work (to which I am strongly opposed :-)
But, I will post it for further exploration. Maybe someone out there has the technical solution, not just a theory. I dont. :-)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exchâ€¦
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that undeâ€¦
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompaâ€¦
Weâ€™ve all felt that sense of false security beforeâ€”locking down external access to a database or component and feeling like weâ€™ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many wâ€¦
###### Suggested Courses
Course of the Month13 days, 11 hours left to enroll