2

I'm struggling with keeping a load of trailing zero's a user has inputted.

I'm using ASP.NET MVC. A user comes to the web page and inputs a number, like as follows:

53.6436717 which is a longitude coordination. in the mentioned example it's not a problem, because all the numbers are preserved.

However 53.6436717000 is different from 53.6436717000000000.

My question is how do I keep the exact value the user has input? I don't wish to trim the zeros, I don't wish to add more zeros on, I just need the numbers to stay as they are. There must be an obvious way?

Liath
  • 9,913
  • 9
  • 51
  • 81
James
  • 1,363
  • 19
  • 28
  • 1
    What type are you using to hold the number? – Richard Sep 04 '14 at 14:39
  • 1
    You're looking for the string type :) 1.7 is mathematically equal to 1.70000000000000 – Ondrej Svejdar Sep 04 '14 at 14:40
  • `decimal` *should* [keep trailing zeroes for you](http://stackoverflow.com/questions/17516460/how-to-format-a-decimal-without-trailing-zeros), although (as Ondrej says) decimal 1.7 will equal decimal 1.7000000.... How are you parsing and displaying when you use `decimal`? – Rawling Sep 04 '14 at 14:42
  • Hello thank you both. currently in a double, I've tried decimals and floats, but no luck. so what do you think, hold as a string and parse it as a....? Like I said I just need to keep the number as input by the users. Thank you – James Sep 04 '14 at 14:43
  • @thomo I've tried to improve this question by formalising it a bit and re-titling to explain the problem rather than the DP issue. Feel free to roll back if you don't agree with anything. – Liath Sep 04 '14 at 14:55

5 Answers5

1

I'm going to be controversial and suggest that actually you are fine using a decimal.

Although you're right that the coordinate value 53.6436717000 is different from 53.6436717000000000 the same position is indicated. What's different is the precision of those coordinates.

My suggestion would be to store these in a decimal with an integer indicating the number of DPs which this coordinate is accurate to.

Using the answer to this question to calculate the number of decimal places

decimal longitude = 0;
decimal latitude = 0;
var precision = BitConverter.GetBytes(decimal.GetBits(argument)[3])[2];

Using this information you can restore these values into strings, display them on a map, add an area of uncertainty to a map, whatever you want!

Community
  • 1
  • 1
Liath
  • 9,913
  • 9
  • 51
  • 81
  • The `decimal` type alreadys remember all trailing zeroes; you shouldn't need to extract the precision and store it separately. (Although: good point if you need to explicitly compare the precision!) – Rawling Sep 04 '14 at 14:55
  • 1
    @Rawling thanks for that, out of interest do SQL decimals behave the same? The point I was trying to make was that in mapping precision often refers to more than the number of zeros though. In British mapping for example (which I'm more familiar with) 458164 and 4581216412 would actually be very close together. By explicitly having a precision you're getting that value from the user rather than the number. – Liath Sep 04 '14 at 14:59
  • 1
    Good point about SQL. SQL decimals are fixed-point so if you wanted to keep the input precision you'd have to keep it separately. – Rawling Sep 04 '14 at 15:02
0

I would suggest storing the numbers as decimal type, as they are more pricise than doubles or floats.

It should like you're having issues when actually displaying the values, and the trailing zeros are being displayed, and not that having the trailing zeros as part of the number is the problem.

If this is correct, use the ToString(string format) method, http://msdn.microsoft.com/en-us/library/fzeeb5cd(v=vs.110).aspx

Example:

double d = 99.3100000;
string s = d.ToString("0.###");
Console.WriteLine(s);

Would be displayed as 99.31. "0" represents a digit, and "#" represents a digit if one exists.

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
Patrick Allwood
  • 1,822
  • 17
  • 21
0

Just save the input as a string. Convert to a decimal only if/when calculations are required, at which point trailing zeros are irrelevant.

Sandy
  • 21
  • 5
  • While this would work I don't like this approach because at the end of a day a number is a number. I get very uncomfortable when people start storing numbers as strings and vice versa. Usually they come on stuck when they need to start doing calculations/filters – Liath Sep 04 '14 at 15:00
0

I would change the type you are using to hold the number to a decimal, that should hold on to the zeroes.

decimal x = 53.6436717000M;

Console.WriteLine(x);

results in:

53.6436717000

If for some reason you can't do that, I am assuming that these coordinates always have the same number of decimal places for your application? If so you could just tack on zeroes to the end of the number when ever you need to display it, like this:

double x = 53.6436717000;

Console.WriteLine(x); // 53.6436717 (missing zeroes)

string y = x.ToString().Split('.').Last();

while(y.Length < 10) // where 10 is the number of decimal places
{
    y+="0";
}

Console.WriteLine(x.ToString().Split('.').First() + "." + y); // 53.6436717000 (with zeroes)
Ben
  • 5,525
  • 8
  • 42
  • 66
-1

The problem you have is because the computer will store 1.25 and 1.250000 as exactly the same pattern of digits (because mathematically they're the same number, after all). When you come to display the number, C# will by default decide how many decimal places to show, but if you've used any of the numeric types it will no longer know how many decimal places the user typed in. Rather than Michael's suggestion, I would store both the number and the number of decimal places. That way you can still do arithmetic on the numbers and you can use the number of decimal places directly in output format statements. I'd probably wrap that up as a new numeric type, too.

digitig
  • 1,989
  • 3
  • 25
  • 45
  • Your first sentence is not true for the `decimal` type. – Rawling Sep 04 '14 at 14:53
  • As far as I can see from the official C# specification, it's not possible to tell whether the representations will be the same or different in the `decimal` type: it's undefined. Yes, you could examine results to see what a particular compiler does, but you can't be sure that will work on another compiler. So unless you have a way of ensuring it in a way that solves the original question, I reckon my solution stands. – digitig Sep 05 '14 at 07:39
  • §2.4.4.2: "Any scale apparent in the literal is preserved ... Hence, the literal 2.900m will be parsed to form the decimal with sign 0, coefficient 2900, and scale 3". §4.1.7 "coefficient c is given by 0 ≤ c < 296" (no restriction to not have trailing zeroes). Although `decimal.Parse` doesn't specify that it keeps zeroes, true. – Rawling Sep 05 '14 at 07:57