VB.NET Rounding

I'm using VB.NET, Visual Studio 2013.

I'm writing a helper utility to export data from a database containing invoicing information. That data comes from another program that generates the invoices and such. I didn't write the invoice program, and I cannot change it.

Basically, my program creates a simple CSV export that the user then uploads to a web portal (it's essentially an "invoice verification system" that compares the physical invoice received by a customer with the data in the invoice database). If the total invoice value is off even by a penny, the system rejects it, and they have to go back and manually verify, which is understandably annoying.

My problem is that when I get the data from the invoicing database, I have to round that data, and all too often I'm off by a penny. For example, I have this number:

26.017278

The invoicing program represents the value of that number as 26.01. My program rounds it to 26.02.

I've tried the various flavors of Math.Round, and each time it rounds to 26.02 (as I kinda expect). I've read up on the Math.Round MSDN article, so please don't link to that - it doesn't help, and in fact it seems Math.Round is doing what it's supposed to do.

 I've tried the function below, which I harvested from the invoice program's DLL file (after deconstructing it, and converting it to VB.NET):

        Dim flag As Boolean
        If dblNumber < 0.0 Then
            flag = True
        Else
            flag = False
        End If
        Dim num As Double = Math.Pow(10.0, CDbl(intDecimals))
        Dim num2 As Double = (Math.Abs(dblNumber) * num) + 0.5
        Dim num3 As Double = Conversion.Int(Conversions.ToDouble("" & Conversions.ToString(num2))) / num
        If flag Then
            num3 *= -1.0
        End If
        Return num3

Open in new window

Even with that - which is the exact code they have, converted to VB.NET - I still get 26.02.

I've tried other Rounding functions I gathered from the web, and they all seem to return 26.02. The only way I've been able to get 26.02 is to convert the value to a string and grab the 2 characters immediately after the decimal point. While this works, it seems as if there should be a way to convert it using numeric values.

Any help would be much appreciated.

BTW, here's the code from the invoicing program, exactly as written:

public double Round2(double dblNumber, short intDecimals)
{
    bool flag;
    if (dblNumber < 0.0)
    {
        flag = true;
    }
    else
    {
        flag = false;
    }
    double num = Math.Pow(10.0, (double) intDecimals);
    double num2 = (Math.Abs(dblNumber) * num) + 0.5;
    double num3 = Conversion.Int(Conversions.ToDouble("" + Conversions.ToString(num2))) / num;
    if (flag)
    {
        num3 *= -1.0;
    }
    return num3;
}

Open in new window

LVL 86
Scott McDaniel (Microsoft Access MVP - EE MVE )Infotrakker SoftwareAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
Use Math.Floor instead of rounding, that puts it to the number lower.  eg 26.017278 will end up as 26.01
https://msdn.microsoft.com/en-us/library/e0b5f0xb%28v=vs.110%29.aspx

ps.  You'll need to multiply then divide by 100.0 as it is integer results.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
*No points*

Proof of concept -
Imports System.Runtime.CompilerServices

Module Module1
	Sub Main()
		Dim value As Double = 26.017278
		Console.WriteLine("{0}", Math.Floor(value * 100) / 100)
		Console.ReadLine()
	End Sub
End Module

Open in new window

Produces the following output -Capture.JPG-saige-
Scott McDaniel (Microsoft Access MVP - EE MVE )Infotrakker SoftwareAuthor Commented:
Thanks - that works perfectly
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.