Error in decimal divide in "?:" operator

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have a web service written in C# Visual Studio 2005 that calculates splits
between two or more timekeepers in a transaction. To set this up I have
several decimal data type variables from one particular timekeeper:

timerRow["diff_time"] = 4.5M
tkRate = 130M
tkAmount = 585M (timerRow["diff_time"] * tkRate)
totalAmount = 1605M (sum of all tkAmounts in the transaction)

I execute the following line of code:

percentOfTransaction = (totalAmount == 0.00M ? 0.00M : tkAmount /
totalAmount);

and get 0.4382022471910112359550561798 however the actual answer should be
0.36448598130841121495327102803738.

If I replace the code with:

percentOfTotal = 0.00M;

if (totalAmount != 0.00M)
{
percentOfTotal = tkAmount / totalAmount;
}

I get the correct answer. The error does not occur for every transaction as
many of the calcuations come out correct. This is the sixth transaction in a
batch of eight and the only one that is wrong.

The other curious thing is that, using the command window, if I type

? tkAmount / totalAmount

it responds with the correct answer and

? percentOfTransaction

yields the erroneous result indicating that the variables are set properly.

Has anyone seen this behavior before as I use this construct a great deal in
checking for divide by zero?
 
The first thing I'd do is put in some parentheses and see if the operator
grouping is what I think it is.
 
JayAchTee said:
I have a web service written in C# Visual Studio 2005 that calculates splits
between two or more timekeepers in a transaction. To set this up I have
several decimal data type variables from one particular timekeeper:

Using your code (roughly), I get:

~$ cat prog.cs
using System;

class App
{
static void Main()
{
decimal diff_time = 4.5M;
decimal rate = 130M;
decimal amount = diff_time * rate;
decimal totalAmount = 1605M;
decimal percent = (totalAmount == 0M ? 0M : amount /
totalAmount);
Console.WriteLine(percent);
}
}

~$ ./prog
0.364485981308411214953271028

Can you reproduce your behaviour in a simple, complete program like the
one above?

-- Barry
 
I would think it was grouping except for the fact that it works seven out of
eight times with sixteen passes through the code (8 transaction * 2
timekeepers)!
--
Regards,

JayAchTee


Michael A. Covington said:
The first thing I'd do is put in some parentheses and see if the operator
grouping is what I think it is.

JayAchTee said:
I have a web service written in C# Visual Studio 2005 that calculates
splits
between two or more timekeepers in a transaction. To set this up I have
several decimal data type variables from one particular timekeeper:

timerRow["diff_time"] = 4.5M
tkRate = 130M
tkAmount = 585M (timerRow["diff_time"] * tkRate)
totalAmount = 1605M (sum of all tkAmounts in the transaction)

I execute the following line of code:

percentOfTransaction = (totalAmount == 0.00M ? 0.00M : tkAmount /
totalAmount);

and get 0.4382022471910112359550561798 however the actual answer should be
0.36448598130841121495327102803738.

If I replace the code with:

percentOfTotal = 0.00M;

if (totalAmount != 0.00M)
{
percentOfTotal = tkAmount / totalAmount;
}

I get the correct answer. The error does not occur for every transaction
as
many of the calcuations come out correct. This is the sixth transaction
in a
batch of eight and the only one that is wrong.

The other curious thing is that, using the command window, if I type

? tkAmount / totalAmount

it responds with the correct answer and

? percentOfTransaction

yields the erroneous result indicating that the variables are set
properly.

Has anyone seen this behavior before as I use this construct a great deal
in
checking for divide by zero?
 
I have not had any luck at duplicating the problem by simplifying the
application. The results are as expected. This one has me and my colleagues
baffeled.
 
JayAchTee said:
I have a web service written in C# Visual Studio 2005 that calculates splits
between two or more timekeepers in a transaction. To set this up I have
several decimal data type variables from one particular timekeeper:

timerRow["diff_time"] = 4.5M
tkRate = 130M
tkAmount = 585M (timerRow["diff_time"] * tkRate)
totalAmount = 1605M (sum of all tkAmounts in the transaction)

I execute the following line of code:

percentOfTransaction = (totalAmount == 0.00M ? 0.00M : tkAmount /
totalAmount);

and get 0.4382022471910112359550561798 however the actual answer should be
0.36448598130841121495327102803738.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
Unfortunately the simplified code does not reproduce the problem. All I have
left of the issue is a screen shot of the debugging session with the watch
variables and command line window output.
--
Regards,

JayAchTee


Jon Skeet said:
JayAchTee said:
I have a web service written in C# Visual Studio 2005 that calculates splits
between two or more timekeepers in a transaction. To set this up I have
several decimal data type variables from one particular timekeeper:

timerRow["diff_time"] = 4.5M
tkRate = 130M
tkAmount = 585M (timerRow["diff_time"] * tkRate)
totalAmount = 1605M (sum of all tkAmounts in the transaction)

I execute the following line of code:

percentOfTransaction = (totalAmount == 0.00M ? 0.00M : tkAmount /
totalAmount);

and get 0.4382022471910112359550561798 however the actual answer should be
0.36448598130841121495327102803738.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
You mentioned evaluating some of the sub-expressions in the debugger? What
if you try evaluate the whole ternary (?:) expression in the debugger - do
you get the same result? Note: not sure if it can do this or not.
 
Kevin, I did not try that... but I can tomorrow. I have set up the
application to fault when the percentages don't add up to 100% and have also
added a check feature using the ?: expression and simple if-then logic. I'll
let you know.
 
JayAchTee said:
Unfortunately the simplified code does not reproduce the problem. All I have
left of the issue is a screen shot of the debugging session with the watch
variables and command line window output.

Sounds like it's more likely to be a debugger issue than anything else,
to be honest.
 
That's what I would have thought except for the incorrect numbers in the time
and billing system! Just a fluke... no big deal. Right!
--
Regards,

JayAchTee
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top