I've got a decimal value, which is stored in my database (SQL Server 2008) with a precision of 13, and a scale of 10.
Examples:
10.6157894734
68.0750000000
96.8723684210
Basically, the numbers represent a "score" out of 100.
Now, i want to display/represent this value a different way, depending on the culture.
For example, in AU, i want to display the value out of 100, rounded up to 2 decimal places.
So in the above example:
10.62
68.08
96.87
But in US, i want to display the value out of 10, rounded up to 1 decimal place.
So in the above example:
1.1
6.8
9.7
Can this be done with a resource-file, e.g doing something like:
return score.ToString(Resources.Global.ScoreFormat);
Where it could be stored as "#.##" in en-US, but "#.#" in en-AU?
I'm pretty sure it can't, since i'm not only rounding, but transforming using Math? (e.g value / 10 for AU) But thought i'd ask the question.
I'm trying to avoid an ugly if statement which checks the current culture and does math/rounding manually.
You will need to put a modifier and a format string in your resources so that you can do something like
return (score * Resources.Global.ScoreModifier).ToString(Resources.Global.ScoreFormat);
Accepting Phil's answer, but this is the actual modifier/format for anyone who cares:
Code:
var formattedScore = (score / Convert.ToInt32(Global.ScoreModifier)).ToString(Global.ScoreFormat))
Global.resx
ScoreFormat n1
ScoreModifier 10
Global.en-au.resx
ScoreFormat n2
ScoreModifier 1
Seems to work..anyone spot a problem?
Related
The Math.Round function isn't supported by LINQ to entities (I assume that means using LINQ with the entity framework dbset) but I really need to round the double in query to filter lots of rows according to the user input.
User input is 4 digits after point and doubles in db can be any size.
Is there a way to round double in the query?
UPDATE:
Basically user enters some number in filter of the table column. Lets say it's a weight of fruits.
So for example user enters weight as 4.2152 and the column must filter all the fruits whose weight is 4.21515 or 4.215212 etc.
And in the database there are many fruits which weight is like 4.21514543543643
RESULT
So after a day long struggle I decided to use the range condition. Although it's not quite a solution. If user enters 4.2152 then range filters with condition bigger then 4.21515. But it will filter out the 4.215149 value which would otherwise be rounded to 4.2152.
The problem is solved but not exactly as needed :(
Instead of trying to round the data on your server, try instead to use some boundaries.
For your example, you basically want all the fruits which weight between 4.2152 and 4.2153 .
Now, it will depend on your specific case, (do you always want a precision of 4 decimals ? What is the exact datatype do you use, etc...), so the exact algorithm is up to you.
But it will looks like this :
double lowerBound = userInput; // 4.2152
double precision = 0.0001;
double upperBound = userInput + precision;
var query = DbSet<Fruit>.Where(f => lowerBound >= f.Weight && f.Weight < upperBound);
Also keep in mind that floating-point arithmetic can surprise you, sometimes. Depending on your usecase, this + 0.0001 might not be exactly what you want.
Update answers:
You can try to use Canonical Functions.
It's have a lot of functions help you in Math.
Maybe it can help. Document
Old answers:
Try use .AsEnumerable() before Where clause.
It's should works.
I'm new to ASP.NET MVC C# Programming
I have a class which contains an attribute called Credits of type double. This attribute should be represented as a Time Format (hh:mm) in my web application. So for example, if I were to give Credits the value of 2.5, I want it to display 2:50, 6.15 as 6:15, etc. I know TimeSpan can convert a double to the time format but it converts 2.5 to 2:30. Is there a way to do easily convert a double to this time format without changing its data type to a String? Is there some sort of helper Attribute tag or something that would make this easy?
It appears that you want to get the whole number and the fractional part separated, and that you want the fractional part as a two-digit number.
So here's how you would get the whole number part as an int.
var whole = (int)Math.Truncate(value);
And this would give you the fractional part as an int, in this case only the first two decimal places.
var twoFrac = (int)(((decimal)value % 1) * 100);
So, if value was 12.345, then twoFrac would turn out to be 34 in int.
Now you can display these whichever way you like.
And you can actually put the above inside of a method so you can get the fractional part up to however many decimal places you want, like this:
private static int GetFractionalPart(double value, int decimalPlaces)
{
var factor = (int)Math.Pow(10, decimalPlaces);
var fractional = (int)(((decimal)value % 1) * factor);
return fractional;
}
NOTE
However, as many others pointed out in comments, this is a confusing and you could even say wrong way of doing things if you're actually dealing with time values. For example, using your criteria, a value of 2.75 would convert to 2:75, but that doesn't mean anything in terms of time.
So you really ought to use TimeSpan as you mentioned in your original post, which would convert 2.5 to 2:30 etc.
This question already has answers here:
How do I display a decimal value to 2 decimal places?
(19 answers)
Closed 8 years ago.
UPDATE
It's so simple...
When I try to convert the value $ 1.50 from a textbox to a decimal variable, like this:
decimal value = Convert.ToDecimal(textbox1.text.SubString(1));
OR
decimal value = Decimal.Parse(textbox1.text.SubString(1));
I get this result: 1.5.
I know that 1.5 and 1,50 worth the same. But I want to know if it's possible to have two digits after the dot on a decimal variable.
I want to have this as result: 1.50 instead of 1.5 even if these two values worth the same...
I want to have this as result: 1.50 instead of 1.5 even if these two values worth the same..
You have 1.50 or 1.500 or 1.5000. all depending on how you decide to format it / print it.
Your decimal value is stored in floating point format. How many decimal points you see is about output, not storage (at least until you reach the limit of the precision of the particular binary format, and 2 decimal places is nowhere close). A C# Decimal stores up to 29 significant digits.
See this reference. It gives an example of a currency format. It prints something like:
My amount = $1.50
But, you aren't storing a $ sign..., so where does it come from? The same place the "1.50" comes from, it is in your format specifier.
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
Console.WriteLine("My amount = {0:C}", x);
var s = String.Format("My amount = {0:C}", x);
It is no different than saying, how do I store 1/3 (a repeating decimal)?
Well, it isn't 0.33, but if I only look at the first 2 digits, then it is 0.33. The closer i look (the more decimal places I ask for in the format), the more I get.
0.33333333333333... but that doesn't equal 0.330
You're confusing storage of the numeric value with rendering it as a string (display).
decimal a=1.5;
decimal b=1.50;
decimal c=1.500;
In memory: the zeros are kept to keep track of how much precision is desired. See the link in the comment by Chris Dunaway below.
However, note these tests:
(a==b) = true
(b==c)=true
Parsing ignores the trailing zeros, so your example one creates them, then they're ignored, as they're mathmatically irrelevant.
Now how you convert to string is a different story:
a.ToString("N4") returns the string "1.5000" (b. and c. the same)
a.ToString("N2") returns the string "1.50"
As the link in the comment explains, if you just to a.ToString, trailing zeros are retained.
If you store it in a database column as type 'decimal', it might be a different story - I haven't researched the results. These are the rules that .Net uses and while the databases might use different rules, these behaviours often follow official standards, so if you do your research you might find that the database behaves the same way!
The important thing to remember is that there is a difference between the way numbers are stored in memory and the way they are represented as strings. Floating point numbers may not retain trailing zeros this way, it's up to the rules of the in-memory storage of the type (usually set by standards bodies in very specific, detailed ways).
I want to change CultureInfo of double or the string.
For example I get double value from the code in format like 3015.0
I don't know in what unit is this but I need value in the meters and these are not in the meters because I am on the altitude of cca.100m
I have tried: double.Parse(test, new System.Globalization.CultureInfo("hr-HR"));
and double.Parse(test, new System.Globalization.CultureInfo());
but nothing is a right format what I need.
Any idea what I can do? This is windows form C# application if this is important. Framework 4.0
EDIT:
As you can see on this LINK I had a similar problem before and it was solved with culture info. Problem is that on picture 1 are the values that I get and on the picture 2 are the real values that I need to get ( when I say real I mean in the right format) I think that problem is in the culture somewhere as on my previously question I had problem with decimal values).
This is not related to Culture info.
Looks like you are getting a measurement in feet while you are expecting it to be in meters. In fact, 100 meters = 328.08399 feet and your measurements might be in 10 feets i.e 3015.0 = 301.5 feet (some GPS receivers do not support floats or doubles and therefore return only integers multiplied by 10 to have one decimal accuracy)
If you are using a cheap GPS receiver than this is expected as the accuracy is not that great (this would explain why you are getting 3015.0 instead of 3280)
I hope this helps.
Your problem has nothing to do with CultureInfo but with unit conversion. Probably you will have to do a unit convertion. Are you sure that the number is not 301.5? This would probably mean that the altitue is given in feet.
double altitudeMeters = 0.3048 * altitudeFeet;
The setting of the current culture will not convert units for you. It only affects the formatting of numbers (for example, some cultures use a comma instead of a period for the decimal point). You'll have to do the units conversion yourself.
double.Parse will simply convert the string into a number. It doesn't do unit conversions. The different culture information is for when there is a decimal comma (e.g. French) etc.
You will have to build some logic into your application to convert the number from what looks like feet to meters. If you can be sure that the data is always going to be in the "wrong" format then a simple feet to meters (1 foot = 0.3048 meters) conversion will work. Given that this is a GPS device you might be able to assume this.
If the numbers can be in any format then you will need to analyse the number and if it's outside the sensible range convert it. However, this will fail if someone enters "100". Is this metres or feet?
To ensure you get the right units you will either have to have the user select the units on a separate control or include the units in the input string. If you do the latter then you'll need to get into parsing the string to see if it contains a units string, stripping it off, parsing the number and the string and then doing the conversion.
Altitude comes from $GPGGA string which indicates the units being used. What does the $GPGGA string look like?
see http://aprs.gids.nl/nmea/#gga
if you look at the raw data in the string you will know if you are collecting the right numbers and their units
Alex
Does anyone know of an elegant way to get the decimal part of a number only? In particular I am looking to get the exact number of places after the decimal point so that the number can be formatted appropriately. I was wondering if there is away to do this without any kind of string extraction using the culture specific decimal separator....
For example
98.0 would be formatted as 98
98.20 would be formatted as 98.2
98.2765 would be formatted as 98.2765 etc.
It it's only for formatting purposes, just calling ToString will do the trick, I guess?
double d = (double)5 / 4;
Console.WriteLine(d.ToString()); // prints 1.75
d = (double)7 / 2;
Console.WriteLine(d.ToString()); // prints 3.5
d = 7;
Console.WriteLine(d.ToString()); // prints 7
That will, of course, format the number according to the current culture (meaning that the decimal sign, thousand separators and such will vary).
Update
As Clement H points out in the comments; if we are dealing with great numbers, at some point d.ToString() will return a string with scientific formatting instead (such as "1E+16" instead of "10000000000000000"). One way to overcome this probem, and force the full number to be printed, is to use d.ToString("0.#"), which will also result in the same output for lower numbers as the code sample above produces.
You can get all of the relevant information from the Decimal.GetBits method assuming you really mean System.Decimal. (If you're talking about decimal formatting of a float/double, please clarify the question.)
Basically GetBits will return you 4 integers in an array.
You can use the scaling factor (the fourth integer, after masking out the sign) to indicate the number of decimal places, but you should be aware that it's not necessarily the number of significant decimal places. In particular, the decimal representations of 1 and 1.0 are different (the former is 1/1, the latter is 10/10).
Unfortunately, manipulating the 96 bit integer is going to require some fiddly arithmetic unless you can use .NET 4.0 and BigInteger.
To be honest, you'll get a simpler solution by using the built in formatting with CultureInfo.InvariantCulture and then finding everything to the right of "."
Just to expand on the point about getbits, this expression gets the scaling factor from a decimal called foo:
(decimal.GetBits(foo)[3] & 16711680)>>16
You could use the Int() function to get the whole number component, then subtract from the original.