Conversion overflows when divide decimal number - c#

There is a property which is decimal I want to divide that on 1,000,000 to change the size of number to shorten one, I declare a variable which is decimal too. when I divide, it raises "conversion overflow"
my code like bellow :
PrmSales and Amt are both decimal,
var amt = (from p in db.FactTotalAmount
group p by p.FromDate into g
select new outputList
{
Amt= (g.Sum(x => x.PrmSales)/1000000)
}

the error is for type of the field in database that is smaller than the type of property in coding because of that I receive that Error.
thank you nilsk !

Related

What is best practice to use when checking if decimal matches a query

I have a for loop that loops a list of transactions, which all contains amount. If the amount is correct, I want that transaction to be included in a new list.
So in code:
decimal searchAmount = 33.03;
foreach (var order in listOforders)
{
if(order.amount == searchAmount)
{
addOrderToList()
}
}
The currency used doesn't use more than two decimals, so that's okay. These three scenarios, should all add the order to the list.
order.Amount = 33.03
search.Amount = 33
order.Amount = 33.03
search.Amount = 33.03
order.Amount = 33.99
search.Amount = 33.9
Note:
This is a search. When the customer comes back, and says "I have a problem with the product I purchased, and it's not purchased on a registered customer", searching for the amount on the customers bank receipt is a great function. This is a retail brick and mortar store scenario, so some customers choose to not register themselves.
If you want to discard the fractional part completely, using a combination of LINQ and Math.Truncate
var orders = listOfOrders.Where(o => Math.Truncate(o.amount) == Math.Truncate(searchAmount))
.ToList();
Math.Truncate returns the integral part of a given decimal, Where selects only appropriate orders (do read up on LINQ's deferred execution if you don't know it) and ToList materializes the query into a list.
EDIT: given your edit, this is probably what you're looking for:
var orders
= listOfOrders.Where(
o => Math.Truncate(o.amount) == Math.Truncate(searchAmount)
&& o.amount.ToString(CultureInfo.InvariantCulture)
.StartsWith(searchAmount.ToString(CultureInfo.InvariantCulture)))
.ToList();
This first verifies if the integral part of the numbers match and then uses string comparison to check if the actual amount starts with what was inputted (by your lazy user).
Use your if condition like this. Round to 2 decimal places and compare.
if((Math.Round(order.amount,2) - Math.Round(searchAmount,2)) <= 0.9M)
{
addOrderToList();
}
What if you use Math.Truncate(number)? Just like:
if(Math.Truncate(order.amount) == Math.Truncate(searchAmount))
If am right you need to do define some maximum difference constant and use it something like that
decimal maxDiff = 0.03;
decimal searchAmount = 33.03;
var result = listOfOrders.Where(o => Math.Abs(o.Amount - searchAmount) <= maxDiff);
You need to use Math.Floor method to match all numbers i.e absolute value
decimal searchAmount = 33.03;
var temp = Math.Floor(searchAmount);
foreach (var order in listOforders)
{
if(Math.Floor(order.amount) == temp)
{
addOrderToList()
}
}
There is no need for any call to Math as a cast to int will do the same. Your code could be changed to;
int searchAmount = 33;
listOforders.Where(o => (int)o.Amount == searchAmount)
.ForEach(o => addOrderToList());

How to convert from decimal to double in Linq to Entity

Suppose we have table T which has two columns A and B with float and money types respectively. I want to write a linq query like following T-SQL statement:
Select A, B, A * B as C
From SomeTable
Where C < 1000
I tried to cast like following
var list = (from row in model.Table
where ((decimal)row.A) * row.B < 1000
select new { A = row.A,
B = row.B ,
C = ((decimal)row.A) * row.B}
).ToList();
but it does not allow the cast operation. It throw an exception:
Casting to Decimal is not supported in Linq to Entity queries, because
the required precision and scale information cannot be inferred.
My question is how to convert double to decimal in Linq? I don't want to fetch data from database.
Update:
I notice the converting decimal to double works but reverse operation throws the exception. So,
Why can't we convert double to decimal? Does Sql server do the same mechanism in t-sql too? Doesn't it affect precision?
The difference between a float (double) and a decimal, is that a float is decimal precise. If you give the float a value of 10.123, then internally it could have a value 10.1229999999999, which is very near to 10.123, but not exactly.
A decimal with a precision of x decimals will always be accurate until the x-th decimal.
The designer of your database thought that type A didn't need decimal accuracy (or he was just careless). It is not meaningful to give the result of a calculation more precision than the input parameters.
If you really need to convert your result into a decimal, calculate your formula as float / double, and cast to decimal after AsEnumerable:
(I'm not very familiar with your syntax, so I'll use the extension method syntax)
var list = model.Table.Where(row => row.A * row.B < 1000)
.Select(row => new
{
A = row.A,
B = row.B,
})
.AsEnumerable()
.Select(row => new
{
A = row.A,
B = row.B,
C = (decimal)row.A * (decimal)row.B,
});
Meaning:
From my Table, take only rows that have values such that row.A * row.B
< 1000.
From each selected row, select the values from columns A and B.
Transfer those two values to local memory (= AsEnumerable),
for every transferred row create a new object with three properties:
A and B have the transferred values.
C gets the the product of the decimal values of transferred A and B
You can avoid AsEnumerable() explaining to Entity how many fractional digits you want.
var list = (from row in model.Table
where ((decimal)row.A) * row.B < 1000
select new { A = row.A,
B = row.B ,
C = (((decimal)((int)row.A)*100))/100) * row.B}
).ToList();

Digit grouping with two decimal places in c#

I want to display a number which is of double datatype in C#, in grouped digits and with two decimal places only if it contains a decimal no.
e.g. If there is 2000.4567 and 2000.45, it must be displayed as 2,000.45 and if it is 2000 then it will displayed as 2,000 (grouped but without decimal).
I have tried this and it is working fine for digit grouping but it rounds off the decimal no. to an integer value either by floor or ceil:
DimensionLength.ToString("#,##0")
DimensionLength is of type double.
Try this Code
double s=123.345345;
string str=string.Empty;
str = s.ToString("#,0.##");
MessageBox.Show(str);
I think you are better off by creating your own custom condition
double _inputval=2000.4567
string _outputVal="";
if ((_inputval % 1) == 0)
{
_outputVal = _inputval.ToString("#,##");
}
else
{
_outputVal = _inputval.ToString("N2");
}
Hope it helps

converting SQL double in String

I am getting a problem when fetching double value from using linq and converting it into string. My code is:-
public List<ShowDataOnClient> GetCardListToShow()
{
try
{
List<ShowDataOnClient> CardList = new List<ShowDataOnClient>();
using (ProgressCardLINQDataContext c = new ProgressCardLINQDataContext())
{
CardList = (from card in c.GetTable<T_PROGRESSCARD>()
where card.RecordStatus.Equals(RecordStatus.Active)
select new ShowDataOnClient
{
Student=(from student in c.T_STUDENTs
where student.Id.Equals(card.StudentId)
select student.Name).Single().ToString(),
Test=(from test in c.T_TESTs
where test.Id.Equals(card.TestId)
select test.Name).Single().ToString(),
MaxMarks = (from test in c.T_TESTs
where test.Id.Equals(card.TestId)
select test.MaxMarks).Single().ToString(),
MarksObtain=card.MarksObtain.ToString(),
Percentage=card.Percentage.ToString()
}).ToList<ShowDataOnClient>();
}
return CardList;
}
catch
{
return new List<ShowDataOnClient>();
}
}
I have tried this also:-
Percentage=Math.Truncate(card.Percentage).ToString()
and when i pass "N2" in ToString it gives exception "Method 'System.String ToString(System.String)' has no supported translation to SQL."
and the value i got after conversion is like this:- 5.200000000000000e+001
is there anybody to help me..
Your ShowDataOnClient class should store the value of Percentage as a double. You can format the way doubles are presented to the user at a later stage. How you do that depends on the control you're using to show the data.
This has the added benefit that sorting functions would work as expected. If you convert your percentage to string this early, sorting by that column won't look right
% as String % as double
1% 1%
10% 2%
11% 10%
2% 11%
23% 23%
etc. etc.
Try this:
double Percentage = card.Percentage;
string PercentageStr = Percentage.ToString();
This will not invoke linq to sql and give you what you want.

An error occurred while updating the entries. xx.xxx Out of range

I have a table with the column
name: variant_markup
datatype: numeric(4,3)
I try to put value 10.000 into it
And I get the Error
An error occurred while updating the entries
10.000 Out of range
It shouldn't be, and I have other columns with same data type and the same process to add a number in, and they don't complain!
The code:
decimal strippedMarkRate = decimal.Round(0, 3);
if (MarkUpTextBox.Text != string.Empty)
strippedMarkRate = decimal.Round(decimal.Parse(toolbox.removeChars(MarkUpTextBox.Text)), 3);
variant_markup = strippedMarkRate;
toolbox.removeChars function just removes any character that isn't a digit or a decimal point from the box, is there a way to do this with regex by anychance?
If you want to insert 10.000 then your data type needs to be defined as numeric(5,3). The first digit in the numeric type declaration is the maximum number of digits in the number (precision). In the case of 10.000, there are 5.
decimal and numeric (Transact-SQL)
decimal [ (p[ ,s] )] and numeric[ (p[ ,s] )]
...
p (precision) The maximum total number of decimal digits that can be stored, both to the left and to the right of the decimal point. The precision
must be a value from 1 through the maximum precision of 38. The
default precision is 18.
s (scale) The maximum number of decimal digits that can be stored to the right of the decimal point. Scale must be a value from 0 through p.
Scale can be specified only if precision is specified. The default
scale is 0; therefore, 0 <= s <= p. Maximum storage sizes vary, based
on the precision.
Perhaps your remove chars isn't doing what you need it to? As to you last question, it would probably be faster to remove the disallowed chars with a foreach statement like so:
StringBuilder sb = new StringBuilder();
foreach(char c in value)
{
if(char.IsDigit(c) || c == '.')
{
sb.append(c);
}
}
return sb.ToString();

Categories