devfric
devfric

Reputation: 7512

ASP.NET MVC DisplayFormat for numeric data is different when left of decimal is 0 and not 1

I am using ASP.NET MVC Core

In have numeric field in my data model with a precision of 6

[Column(TypeName = "decimal(18,6)")]
public decimal? MyNumeric { get; set; }

I my view model it has a display format attribute with DataFormatString property to force it to the 6 precision. I used the DataFormatString MSDN article to lookup the appropriate format.

[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:G6}")]
public decimal? MyNumeric{ get; set; }

If I type in the value as

1,00001

The validation returns it as

1,00001

for

1,000001

The validation returns it

1.

However the problem occurs when I use leading zeros. Using the same above 2 examples but instead with a leading 0 instead of 1

If I type in the value as

0,00001

The validation saves returns it as

1E-05

and not 0,00001 as I would expect for

0,000001

The validation returns it

1E-06.

and not 0 as I expected

So the behaviour differs if it is a leading 0 or 1.

How do I make the validator not treat 0 integer values like that but behave same like the integer value was 1 without the "E" in the output

I want the validation to return a numeric value with trailing zeros removed. However because the above problem if the first value is 0 I am forced to use another format {0:F} but this doesn't remove the trailing zeros.

Upvotes: 1

Views: 779

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239290

Think back to high school. That was probably the last time you heard the term "significant digits". This is essentially a rounding error caused by adherence to significant digits. In the first example, the leading 1 provides your significant digit, so the remainder doesn't need to be preserved. Since, then, you're only including 6 digits of a 7 digit number, .NET simply rounds off the last digit, which since it's less than 5 becomes 0.

In the second example, there's no significant digit until the 7th digit, which means that 7th digit needs to be preserved, even though you're only allowing 6 digits. Therefore, .NET switches to exponential notation to preserve that digit while complying with the total digit length.

Long and short, there's not much you can do about it other than expanding the range of digits captured in the format string (i.e. G7 instead of G6). However, depending on the number type you're using some rounding will be inevitable unless you use the exact precision number for that type: 7 for Single, 15 for Double or 29 for Decimal.

UPDATE

FWIW, if you format the number as string, you can then remove any trailing zeros via TrimEnd('0').

Upvotes: 1

Related Questions