I have a problem I have not found any solution to:
I am getting data from a SAP system, which I receive as decimal. Sometimes I get values with one decimal place, ex. -18083195.1
My 3rd party front-end table framework needs it to be -18083195.10, because sometimes users want to copy the value between cells and the framework converts -18083195.1 to -180831951 in the copy event.
Without converting between decimal and string, I need to assert that the values always are in the the 0.00 decimal format, and of decimal type.
How can this be achieved?
You can check that the value is a decimal type using sample.GetType() == typeof(decimal).
Thanks for all your suggestions!
I found the error, and it was in my table-framework (Handsontable), where, of course, the values are converted to string and back. Due to the varying demands of the client, they wanted a specific format for percentage values, another for regular values, which confused the framework number format functionality. I found a way to work around that!
Thanks!
Fredrik
Related
I have a legacy application where the DeductibleAmount is set to value 250.0. In my application I have to match to it exactly.I tried
decimal.Round(ruleDeductible.Amount, 1)
but it still shows 250 not 250.0.
Is there any way to assign ruleDeductible.Amount the decimal value with a single decimal place.
The output of the method is passed to WebApi and the final output is json. When I compare legacy and the new system json, I see the difference in the number of decimal points.
The point is that I was trying out to match the legacy and the new system output via the Api Responses which is the json in the end. So I have to deal with the formatting in json which is suggested by #Dan Rayson. Handling decimal places of decimal numbers in WebApiResponse
Is there any possibility to force a parameter tpye to accept only a given format and not only in runtime?
What I mean, for instance I have a method:
public void AcceptTest(double version)
{
}
This method will accept 1.0 but 1.00, 1.0067 and so on.
How can I solve to accept only x.y and nothing else but without check it from code by String.Format or something else.
So I don't even give the possibility to write an unacceptable format in the code editor also.
Thank you!
Your goal is not quite clear, and depending on it any number of answer are possible. Including several that read "you are on a poor track" and "that is impossible".
You can not with Double. Double is defined as a number with a high possibility for decimal places. Every number from it's range is viable, both at compile and runtime.
You could round it automatically, wich might be considered poor behavior.
You could check if the "input" is the same as the "input rounded to the 1st decimal digit" (to see if the other party did the rounding for your).
Note that float imprecision will still result in ending up with wierd decimal places. This is a inherent part of floating point numbers:
https://www.youtube.com/watch?v=PZRI1IfStY0
Some implementations of decimal allow you to specify how many digits after comma to allow. But the .NET one is not among them. At least it avoids the decimal imprecision by lowering the value range.
You could just store as (unsigned) integer. Setting the comma during output would become a display side thing. Maybe make your own structure for this so you can provide your own ToString().
Hop that helps, but calrification would be nessesary. In particular your goal and intention. or the specific problem that makes such a limitation nessesary.
I have a simple string received via a parameter:
"1.00"
Based on locale of visitor it sometimes converts to:
"1" or "1,00"
The second one is a problem, I always need it to be a period (dots). $,£
I am using:
decimal price = Convert.ToDecimal(stringPrice, new CultureInfo("en-GB"));
Why is it still converting to "1,00" decimal if I use en-GB culture? I tried InvariantCulture, and the same thing happens. Why is this happening? It shouldn't matter because it's on the back end, right?
The conversion is going fine - internally, you get a decimal representation of 1.00 in your variable (price). Whether you see "1,00" or something else depends on where you are outputting the variable. Please look at how you are printing it, to see how it should display.
I have little experience with MongoDB. I am usual working on large scale SQL server DBs.
MongoDB only supports double and there is no decimal. The C# driver serializes decimals as strings.
What functionality do I miss if I store decimals as strings in
MongoDB?
Is there a way to set a default serialization of decimals as double
(AllowTruncation) without having to put an Attribute on each
property?
What do I lose in precision if I used Bson double?
Thanks for your help!
UPDATE
I have an existing application model that uses decimals in C#. I want to use MongoDB as a new DB layer and change as little in the existing app as possible. Thats why I am looking for a way to map decimals in C# to double in MongoDB.
I understand that I loose precision and would have to analyze the side effects of it. My only remaining question is to know if there is a way to set a default serialization of decimals as double.
Thanks again. Great answers and comments so far.
As of Mongodb 3.4 and the 2.4 Mongodb C# driver, decimal types are supported.
The properties of your document must have the [BsonRepresentation(BsonType.Decimal128)] attribute found in the MongoDB.Bson.Serialization.Attributes namespace.
this will map to "YourDecimalValue" : NumberDecimal("100.0000") in MongodDB. Robomongo supports the new decimal type from version 1.1 Beta.
I will answer your question partially (because I do not know much about C#).
So what will you lose if you will store decimals as strings.
your numbers on average would weight more (each double number cost 8 bytes to store which means that every string that has more then 8 chars will weight more). Because of these your indexes (if they will be built on this field would grow)
you will not be able to use operators which takes numbers as arguments $inc, $bit, $mod, $min, $max and in 2.6 version $mul. (May be I forgot something)
you will not be able to compare numbers (may be '1.65' and '1.23' is comparable as a string, but definitely not numbers with e and minuses somewhere in between). Because of this operations which build on top of comparison like $sort, and all these $gte, $gt, $lte, $lt will not work correctly.
What will you lose in precision if you store decimal as double:
based on this, Decimal in C# has 28-29 significant digits, whereas looking at my first link and checking the spec for double precision you see that it has 15-17 significant digits. This is basically what you will lose
another really important thing which people sometimes forget when dealing with double floats is illustrated below:
.
db.c.insert({_id : 1, b : 3.44})
db.c.update({_id : 1},{$inc : {b : 1}})
db.c.find({b: 4.44}) // WTf, where is my document? There is nothing there
Regarding the 2-nd subquestion:
Is there a way to set a default serialization of decimals as double
(AllowTruncation) without having to put an Attribute on each property?
I do not really understood it, so I hope someone would be able to answer it.
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