Runtime: Make decimal API more complete (number of decimal digits, equality, negative zero)

Created on 2 Apr 2018  路  5Comments  路  Source: dotnet/runtime

@GSPP commented on Mon Apr 02 2018

  1. It is currently not possible to query the number of decimal digits in a decimal value. Note, that decimal can store trailing zeroes. 1m != 1.0m != 1.00m. There are methods to find out but they are nasty (https://stackoverflow.com/questions/13477689/find-number-of-decimal-places-in-decimal-value-regardless-of-culture). A fundamental type such as decimal should make this easier. GetBits causes an expensive allocation.
  2. All Framework provided decimal equality comparisons treat trailing zeros as irrelevant. All of the following are true: 1.0m == 1.00m, 1.0m.Equals(1.00m), 1.0m.GetHashCode() == 1.00m.GetHashCode(). This is correct but there also should be a way to compare while being sensitive to trailing zeroes. There need to be equality and hash code APIs observing trailing zeroes.
  3. Be able to reflect over negative zero. There are multiple representations for zero in decimal (https://stackoverflow.com/a/3139783). decimal.GetBits(0.0m) != decimal.GetBits(-0.0m) and -0.0m == 0.0m. There should be an IsNegative property. Note, that (-0.0m).ToString() == "0.0". This means that the sign cannot even be found out from the string representation.
  4. Maybe there should be more helper APIs around trailing zeroes. For example, an API to set the number of decimal places. This API would add or remove trailing zeroes. I believe the Round methods only remove but do not add zeroes.

These API requests are motivated by my work on a financial application. Different 3rd party data sources needed to be interpreted and combined in awkward ways.

Dealing with these issue should not be that hard. The internet is full of people trying to solve these various decimal issues. There should be obvious and simple framework methods. Using code from the web (Stack Overflow) to address any of this is very risky because the code might be faulty.


@RussKeldorph commented on Mon Apr 02 2018

@danmosemsft


@danmosemsft commented on Mon Apr 02 2018

@tannergooding any thoughts?


@danmosemsft commented on Mon Apr 02 2018

Since this includes API requests. moving to corefx.

api-suggestion area-System.Numerics

Most helpful comment

Please explicitly (re)consider adding a non-allocating variant of GetBits(). There have been several tickets for this (like dotnet/runtime#18969 and dotnet/runtime#18970), but these tickets have been closed to be subsumed by more general Span related tickets, at which point Decimal invariably gets forgotten.

Next, besides knowing the number of decimal digits and negative zero, consider adding a Normalize method that, well, normalizes/canonicalizes Decimals. At the moment, when you receive a Decimal from e.g. SqlClient, it will always be of the same scale as the database field, and when serialized or formatted, the values are always written with trailing zeroes, without any supported way of leaving these out. And using the allocating GetBits() method to mess with Decimals internal structure should not be necessary.

All 5 comments

Please explicitly (re)consider adding a non-allocating variant of GetBits(). There have been several tickets for this (like dotnet/runtime#18969 and dotnet/runtime#18970), but these tickets have been closed to be subsumed by more general Span related tickets, at which point Decimal invariably gets forgotten.

Next, besides knowing the number of decimal digits and negative zero, consider adding a Normalize method that, well, normalizes/canonicalizes Decimals. At the moment, when you receive a Decimal from e.g. SqlClient, it will always be of the same scale as the database field, and when serialized or formatted, the values are always written with trailing zeroes, without any supported way of leaving these out. And using the allocating GetBits() method to mess with Decimals internal structure should not be necessary.

Going to close this as currently unactionable as it is not something we could take to API review.

If someone feels strongly about this, please feel free to open a new issue for the desired scenario. Our API review process is detailed here with a "good example" being listed under step 1. Ideally the new issue would provide many of the sections given, but would at a minimum provide the base rationale and proposed API surface sections.

Decimal is a very core type. The features proposed here seem very essential to me. In my opinion, the team should pick this up even if no outside API proposal is being submitted.

Decimal is a very core type. The features proposed here seem very essential to me.

There are a lot of types, they all need love, and everyone has a different idea of what is "core" or "essential".

In my opinion, the team should pick this up even if no outside API proposal is being submitted.

I could certainly create proposals from the points given above, but they would be missing a lot of core details that I may not be able to articulate or come up with answer for. This is because I'm not the one asking for the changes, I'd only be relaying a request and so I can't answer things like the driving need behind it or what users are currently doing to workaround the lack of the API. So when they eventually go to API review and the rest of the review team start asking questions, I might not be able to provide the right answers to ensure it does get approved. In some cases, the team may not have the same understanding of how the type is or should be used (there is a lot of code out there and it is impossible for us to see it all, especially when much of it is closed source).

This is why users who have specific needs should feel empowered to create individual proposals describing a concrete ask, so that we have something actionable to take forward to API review and so that the driving need and desire behind the change can be properly understood.

Also whenever the community helps define an API that also helps suggest that there'll be real interest in using it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chunseoklee picture chunseoklee  路  3Comments

jamesqo picture jamesqo  路  3Comments

jzabroski picture jzabroski  路  3Comments

aggieben picture aggieben  路  3Comments

omajid picture omajid  路  3Comments