13

It seems like there would be a ton of uses for a fixed point data type. Why is there not one in .NET?

Note: I understand we can create our own classes/structs to suit our fixed point purposes and needs. That's not my question. I want to know WHY MS decided not to include a fixed point numeric data type.

richard
  • 12,263
  • 23
  • 95
  • 151
  • Check this thread http://stackoverflow.com/questions/605124/fixed-point-math-in-c – JonH Feb 21 '11 at 18:30
  • I think you'll find some in Direct3D and OpenGL libraries. If I understand the question correctly. – Tedd Hansen Feb 21 '11 at 18:33
  • Thanks, I read that one already. :-) That's exactly what I'm talking about, there are many real needs for fixed point math. – richard Feb 21 '11 at 18:33

3 Answers3

12

You're looking for the little-known System.Data.SqlTypes.SqlDecimal class.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 7
    @SLaks please edit your original answer don't post multiple answers. – JonH Feb 21 '11 at 18:44
  • Not quite sure why SqlDecimal is better than Decimal. IIRC, it does not preserve scale or precision during arithmetic operations. It only allows you to explicitly adjust it's scale. But so does Decimal.Round. – Ruben Feb 21 '11 at 18:54
  • @Ruben: SqlDecimal is fixed-point; Decimal is floating-point. I've never used it (Sql), though. – SLaks Feb 21 '11 at 18:55
  • 1
    @SLaks: SQL's decimal(p,s) is fixed point; .NET's SqlDecimal is floating point: you can assign numbers with *any* scale to an SqlDecimal (within limits of course). Also, arithmetic operations on SqlDecimal *do not guarantee to preserve scale*. Which by definition means that SqlDecimal is a floating point type. SqlDecimal only stores the scale for reference and rounding purposes *for a specific instance*. – Ruben Feb 22 '11 at 14:24
  • 3
    @JonH: As Ruben says, this is not a pure answer. SqlDecimal is designed specifically for SQL; for general use, `Decimal` **was** deemed good enough. My two answers have nothing to do with each-other. – SLaks Feb 22 '11 at 15:47
  • It seems like SQLDecimal is floating point where the point is fixed by the instantiation. Is that correct? – richard Feb 24 '11 at 17:38
  • @MikeJohnson: Had it been that simple, it wouldn't be 3K+ lines – SLaks Aug 22 '13 at 15:21
8

Decimal (base-10 floating point) was deemed to be good enough.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 4
    So I guess it was deemed good enough for the 80% cases, and they left the 20% up to us to create our own structs? Seems like at least ONE fixed point type would be included! – richard Feb 21 '11 at 18:35
  • 6
    I don't understand that answer. He asks for fixed point and you come up with another floating point type ? – SQL Police Jun 14 '15 at 13:58
  • 2
    @SQLPolice: No; he asked _why_ the BCL doesn't have any. – SLaks Jun 14 '15 at 15:21
  • It's worth noting that the material referenced contains no reference to fixed-point, much less a "why", so not exactly a slam-dunk answer to the OP. For people (like me) who are trying to understand this I find this answer falls into the category of "accurate but not entirely helpful". A bit more supporting elaboration in the post would have been useful. – Adrian K Oct 13 '22 at 03:44
6

One problem probably has to do with the question: where do you fix the point? A type in .NET cannot be parametrized by other arguments than types, so FixedNum<18,6> is simply not possible. And you do not want to create FixedNum1x0, FixedNum1x1, FixedNum2x0, FixedNum2x1, FixedNum2x2, etc.

You need to be able to parametrize your fixed point type, not just values, because that would lead to nigh impossible to track mistakes:

FixedNum f() { return new FixedNum(1, decimals: 2); }

FixedNum x = new FixedNum(1, decimals: 0);
...
x = f(); // precision of x increased.

So you'd need to check and constrain your fixed point values every time you get them from something that's not a local variable. As you do with decimal when you want a fixed scale or precision.

In other words, given the limitations of the .NET type system, decimal is already built-in implementation of the FixedNum class above.

Ruben
  • 15,217
  • 2
  • 35
  • 45
  • 4
    Agreed, except `decimal` is NOT a FixedNum implementation, it is a floating point type - only it is base 10 rather than base 2. – chiccodoro May 08 '13 at 07:13
  • 1
    @chiccodoro: FixedNum class in the last paragraph refers specifically to my imaginary type in my counter example. You're quite right that decimal is a floating point type, but so is the FixedNum in my example. – Ruben May 08 '13 at 16:10