When 5.95 does not equal 5.95

People like nicely formatted numbers on their reports and web pages. For example, if I needed to display the results of a division where the dividend is 1 and the divisor is 3, typically I would display that as 0.3 (the number formatted to 1 decimal place) instead of 0.3333333.

So imagine my surprise when I had a single detail line in my report where a value is shown as 6.0, but in the total line right below it (which utilizes the same data since there is only the one detail line), the same value is displayed as 5.9.

We finally tracked the problem down to a conversion between a float to a double. It appears that the .NET runtime is not able to take a float value of 5.95 and convert it exactly to a double of 5.95, the conversion sets the double to 5.94999980926514. As a result, when this value was sent into the string formatting function, the value would round down instead of rounding up. Keep in mind that the divisions actually come out right, whether they are floats or doubles. As I stepped through the code, all looked well since the float variable was calculating as 5.95 (119 divided by 20), but this was of course before the conversion and formatting.

As I think about it, I was pretty lucky to find this little glitch, as it will only manifest itself when for certain dividends when the divisor is a multiple of 20. (The 1 decimal place round off error happens at multiples of 0.05, or 1 / 20.) Feeling interested, I decided to do a little experimentation. I am married and over the hill, what else am I going to do on a Friday night?

I set up a .NET C# console application to test out the divisions, conversions, and string formatting, and reporting on when the formatted string of the double varies from the formatted string of the float converted to a double. The divisor would loop from 20 to 1000 by 20, and the dividend would loop from 1 to 1000. The final results were:

Divisions tested: 50000
Divisions failed: 916
Failure percentage: 1.83 %

As expected, the divisor of 20 shows the most variations, and dropped off to only 4 variations with a divisor of 1000 (at 350, 450, 650, and 950).

The moral of the story is when it comes to floats, just say no. We went into the code and removed all the float variables and casts and changed them all to doubles.

Stanford iPhone App Programming lectures 6 and 7

Lectures 6 and 7 from the Stanford University iPhone Application Programming class contain a lot of useful information regarding the theory and usage of view controllers in general and navigation controllers and tab bar controllers in specific.

It took a bit of digging to figure out what Evan Doll’s shirt said in lecture 7, but apparently there is a band out there called Blitzen Trapper.

CodeStock 2009

CodeStock 2009 is rapidly approaching, and an associate of mine at the office is attending this year’s conference with me. If you happen to be attending the conference, and notice a loud troublemaker somewhere in the vicinity, it would be my associate. Just be careful giving your business card to him, he is likely to use one of them for his only phone call, as I told him that if he needed bail money, he is on his own.

VB.NET ListBox does not scroll all the way to the bottom when setting SelectedIndex

I have a standard Windows list box that I am using in my Visual Basic .NET application. I am adding records into this list box by binding it to a data source that reads records from a local database and uses a display member in the class to chew on the record and spit out the text. Then, I logically want to see if there are records in this newly minted list box, and if so, set the selection to the last record in the list, which should scroll to the bottom of the list in the event that there are more records to display than lines in the list box. The code:

lstRecords.DataSource = DataLayer.GetRecords(theID)
If lstRecords.Items.Count > 0 Then
    lstRecords.SelectedIndex = lstRecords.Items.Count - 1
End If

Unfortunately, this code does not work 100% as expected. If there are more records than rows available in the list box, the final row does get selected, as the blue selection bar lands on that row. Once you scroll the list down one row to see it. For some reason, the scrolling down of the list box comes up one row short when done this way, no matter how many rows beyond the limit of the list box are added.

I tried everything I could think of, mostly manipulating the properties of the list box to see if some combination worked. I called the Update and Refresh methods, set the TopIndex and IntegralHeight properties, and lots of other things that did not have any effect.

I finally decided to try to set the SelectedIndex property in a timer event. The timer is initially disabled with an interval of 5 ms, and instead of setting the SelectedIndex property as shown in the line above, it enables the timer. And here is the code that executes when the timer fires:

tmrScrollToEnd.Enabled = False
lstRecords.SelectedIndex = lstRecords.Items.Count - 1

And of course, for some reason that escapes me, this now works. Perhaps it is because the setting of the SelectedIndex is moved outside of the Form Load code, which is where the code above was being executed. If anyone has any ideas, I would love to hear them, but I am glad that it is now working.

Stanford iPhone App Programming lectures 4 and 5

I just finished going through lectures 4 and 5 of the iPhone Application Programming class from Stanford University, and learned some more new things that I did not know. Especially interesting was the Stalker demo application that they did at the end of lecture 5, it was kind a neat little demonstration of animating views.

A whole year of more randomer-ness

Today is the 1 year anniversary of a snippet of our company’s code being featured on The Daily WTF web site.  Here is a direct link to the article so you too can bask in the goodness of real randomicity:

More Randomer

So I bought cupcakes for our dev team and decided to hack one of the cupcakes:

More Randomer's First Birthday

By the way, the developer that created the code in question is no longer at the company.

Stanford University iPhone Application Programming class

I have been checking out some of the lecture videos for the Stanford University iPhone Application Programming class CS193P, and I think they are very well done. I have been doing iPhone development for a little while now, and even though I am familiar with quite a bit of what they are presenting, there are still some things in each lecture that I did not know or was not crystal clear on the concepts for.

Here is a link to the course page on Stanford’s web site:

CS 193P — iPhone Application Programming

In order to watch the videos of the lectures, you have to download them into your iTunes through iTunes U. There are also PDF files on the above web page that contain the slide presentations used during the lectures, along with the class assignments and other documents.

So far, I have gone though the first 3 lectures. They do move a bit slowly when questions bog down the presentation, but you can’t beat the price, and other than the first introductory lecture, there should be value in each lecture for most iPhone developers.

Columbus iPhone Developers User Group (CIDUG) meeting

The May CIDUG meeting was last night at the OCLC campus, and Marc Peabody of EdgeCase did a nice job showing some of the intricacies of Objective-C. Overall, I liked his presentation and humor, but I did find one egregious error in his slides:  guitars are way, way cooler than Miles Davis.

Anyone in the central Ohio area who is interested in development for the iPhone should plan to attend the CIDUG meetings.  Here is the Google Groups link for CIDUG:

Columbus iPhone Developers User Group (CIDUG)

Terminator Salvation movie night

We went out after work today to take in the newest installment of the Terminator saga, Terminator Salvation. The movie itself was somewhat disappointing, but as a team building exercise, the camaraderie was worth the effort.

I have a theory about movies. The ability for a movie to interest viewers with plot and conflict is inversely proportional to the amount of special effects. Terminator Salvation does nothing to refute my postulate.

If at first you don’t succeed, try try (catch catch) again

So I am cruising through the ASP.NET C# MVP web project we are working on, and happened upon this method (again, the names were changed to protect the not so innocent):

private void mView_LoadObjects(object sender, EventArgs e)
{
    try
    {
        try
        {
            BusinessLayer.Class1 bizClass = new BusinessLayer.Class1();
            mView.objects = bizClass.GetObjects(mView.ID1, mView.ID2);
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
            throw;
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
        throw;
    }
}

However, the fun didn’t stop there.  A little further down the class, I found this:

private void mView_LoadOtherObjects(object sender, EventArgs e)
{
    try
    {
 
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
        throw;
    }
}

I am thinking that the catch block on this second example was not hit very often.