.NETGURU
Decimal: fixed-point or floating-point
Messages   Related Types
This message was discovered on microsoft.public.dotnet.framework.clr.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
Post a new message to this list...

Jon Skeet [C# MVP] (VIP)
It's been pointed out to me that, contrary to my long-held beliefs, the
documentation for System.Decimal claims that it's a fixed-point data
type. I reckon this is entirely incorrect - it's a floating-point data
type in base 10.

After all, here's another section from the docs:

<quote>
The binary representation of an instance of Decimal consists of a 1-bit
sign, a 96-bit integer number, and a scaling factor used to divide the
96-bit integer and specify what portion of it is a decimal fraction.
The scaling factor is implicitly the number 10, raised to an exponent
ranging from 0 to 28.
</quote>

and here's the FOLDOC definitions of floating-point and fixed-point:
<fixed-point>
The binary representation of an instance of Decimal consists of a 1-bit
sign, a 96-bit integer number, and a scaling factor used to divide the
96-bit integer and specify what portion of it is a decimal fraction.
The scaling factor is implicitly the number 10, raised to an exponent
ranging from 0 to 28.
</fixed-point>

<floating-point>
A number representation consisting of a mantissa, M, an exponent, E,
and an (assumed) radix (or "base") . The number represented is M*R^E
where R is the radix - usually ten but sometimes 2.
</floating-point>

If I'm wrong about this, and decimal really *is* a fixed-point, could
someone post a link to a definition of fixed-point which fits in with
that? Otherwise I'll mail MSDN and let them know that they're talking
rubbish :)

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Peter Vervoorn
"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

It does fit my definition ;)
I always looked at a Decimal as some sort of BCD encoded value, where you
specify the number of digits available behind the decimal point.
(i.e. 5 decimal digits)

With floating point you get an increased accuracy if the integer part
approaches zero.

I hope you understand what I mean, and that I'm not totally wrong with this
:)

Peter

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Peter Vervoorn <Click here to reveal e-mail address> wrote:
[Original message clipped]

That's exactly what a floating-point value is though. In what way is
the point "fixed" if you specify the number of digits behind the it?

[Original message clipped]

Could you elaborate? I suspect you're talking about something which is
a byproduct of how binary floating point happens to be implemented, but
isn't fundamental to floating-point itself.

[Original message clipped]

I don't understand exactly what you mean, and I *think* you're still
wrong - but if you could provide any "standard" definitions which
support your point of view, I'm certainly open to being proved wrong :)

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Peter Vervoorn
"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

If we have 10 positions in total and specify a scale of 4 that leaves 6
digits for the integer part. If the decimal value is 0 (which could be done
with a scale of 0) the point doesn't move, so you still have 6 integer
digits. The position of the point is fixed once it has been set.

Since Decimals are valuetypes the scalingfactor isn't preserved when you
asign a new value, so it is not very usefull I guess.
Decimal a = new Decimal(5,0,0,false,1);
Decimal b = new Decimal(5,0,0,false,1);
Decimal c = new Decimal(0,0,0,false,1);
c = Decimal.Multiply(a, b);
c's value is now 0.25 which should not have been possible, it should have
been 0.2 or 0.3 because we have set the fixed nr of decimals in the
constructor. (IMHO of course.)

[Original message clipped]

If we have only 4 bits available, and want to write 1.5 that could be:
1100 3 (1*2^0 + 1*2^-1 + 0*2^-2 + 0*2^-3 = 1 + 0.5 + 0 + 0)
3 specifies the location of the 2^0 bit.
This leaves 3 bits for creating the decimal part consisting combinations of
1/2 + 1/4 + 1/8.

7.5 that could be:
1111 1 (1*2^2 + 1*2^1 + 1*2^0 + 1*2^-1 = 4 + 2 + 1 + 0.5 = 7.5)
We can only specify 0 or 0.5 for the decimal part here, we only have 1 bit
(2^-1) available.

[Original message clipped]

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Peter Vervoorn <Click here to reveal e-mail address> wrote:
[Original message clipped]

But it's not set by the type itself, it's set by the value. It's
floating in that it can appear in different places depending on the
value.

Besides, the same is basically true for binary floating point, isn't
it? Once the exponent is set, that defines how many bits are before the
binary point and how many are after it.

[Original message clipped]

Whereas IMO we fixed the number of decimals for the two numbers we
created, not the result of the multiplication.

[Original message clipped]

So by "the integer part" here, do you mean "the bit before the decimal
point" rather than "the mantissa"? If so, that's true for decimals as
well. If you've got 15000.something you get fewer decimal digits to
play with for the "something" than if you've got 15.something.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Peter Vervoorn
"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

I always assumed fixed point meant that you set the scale once and then all
values assigned to that variable will use that scale, and floating point
meant the scale was set each time a value was assigned.

This document seems to support this:
"Fixed-point has a fixed window of representation, which limits it from
representing very large or very small numbers. Also, fixed-point is prone to
a loss of precision when two large numbers are divided. Floating-point, on
the other hand, employs a sort of "sliding window" of precision appropriate
to the scale of the number. This allows it to represent numbers from
1,000,000,000,000 to 0.0000000000000001 with ease." (from:
http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html )

[Original message clipped]

True.
However, my point was that I would like to specify the scale of a variable
and as long as the variable is in scope it keeps that same scale, whatever
the value assigned to it.
Since Decimal is a valuetype this is not possible.

Regards,

Peter

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Peter Vervoorn <Click here to reveal e-mail address> wrote:
[Original message clipped]

That's a very specific idea of fixed-point which would only apply to
variables, rather than values themselves.

It's slightly wider than that: the idea of fixed-point is that you set
the scale once and then all values *of that type* will use that scale.

Floating point does indeed mean that the scale is set in each value. I
don't think the concept of assignment and variables comes into this at
all though.

[Original message clipped]

I don't see how that supports what you were saying, to be honest.

[Original message clipped]

It wouldn't be possible if Decimal were a reference type, either -
assigning a different value to the variable would do exactly that. With
either reference types or value types you could create a type so that
multiplying one value by another always resulted in a value which used
(say) the maximum of the scales of each of the values. That's not what
happens though, and I think that would be a fairly odd type, to be
honest.

I'm now unclear whether you still think decimal is fixed-point or
not...

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Peter Vervoorn
"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

That's a very specific idea too ;)
Where would you set the scale?

[Original message clipped]

When the scale is set, the window is fixed and you can only represent a
part of all the possible values.

[Original message clipped]

I guess it is floating, because it is not fixed in the defintion of Decimal,
and you can't specify the scaling yourself anywhere.

Peter

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Peter Vervoorn <Click here to reveal e-mail address> wrote:
[Original message clipped]

Well, it has wider application than one which requires

> Where would you set the scale?

In the type itself, where everything else is set. So just as
System.Double defines there to be 52 bits of mantissa, 11 bits of scale
and 1 bit of sign, you could have a fixed binary point type which had
63 bits of mantissa, 1 bit of sign, and a scale which was always (say)
512. Instead of using 11 bits to represent the scale, they'd be extra
precision, at the cost of range. You'd always have the same number of
bits before the binary point (even if some were zero) and the same
number of bits after the binary point (even if some were zero).

Just to make this all a bit more concrete, here's a simple fixed-point
type:

using System;

/// <summary>
/// Fixed point type which always has two decimal places.
/// </summary>
class FixedPoint
{
int unscaled;

public FixedPoint (int unscaled)
{
this.unscaled = unscaled;
}

public static FixedPoint operator *(FixedPoint x, FixedPoint y)
{
long a = (long)x.unscaled * (long)y.unscaled;
return new FixedPoint ((int)(a/100));
}

public static FixedPoint operator +(FixedPoint x, FixedPoint y)
{
return new FixedPoint (x.unscaled+y.unscaled);
}

// In real life you'd define other operators here, of course

public override string ToString()
{
int abs = Math.Abs(unscaled);
return String.Format("{0}{1}.{2:d2}",
unscaled < 0 ? "-" : "",
abs/100,
abs%100);
}
}

class Test
{
static void Main()
{
FixedPoint two = new FixedPoint(200);

FixedPoint twoPointFive = new FixedPoint(250);

Console.WriteLine (two+twoPointFive);
Console.WriteLine (two*twoPointFive);
}
}

Here the scale is fixed at 1/100. In other words, the actual value is
the unscaled value divided by 100. The fact that it's not divided by
something which is specified in the value is what makes this type fixed
point rather than floating point.

[Original message clipped]

But the scale is just as "set" in a System.Double... You were using
that quote to support this quote:

<quote>
I always assumed fixed point meant that you set the scale once and then
all values assigned to that variable will use that scale, and floating
point meant the scale was set each time a value was assigned.
</quote>

The quote from the web page doesn't support that as it doesn't mention
variables at all.

[Original message clipped]

Well, you specify the scale when you create the instance - either
implicitly or explicitly. Exactly the same is true with System.Single
or System.Double, except they don't provide constructors to separate
out the parts like System.Decimal does.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Peter Vervoorn
"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

This is the source of the difference, when it is defined inside the type
somebody who is using the type cannot set it either implicit or explicit.
If this is a requirement for fixed point types then Decimal is floating
point (in that case my definition for fixed point was wrong).

Regards,

Peter

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Peter Vervoorn <Click here to reveal e-mail address> wrote:
[Original message clipped]

Indeed.

[Original message clipped]

That's certainly my understanding of fixed point types.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Christoph Nahr
That's an interesting subject but you posted the MSDN Decimal docs
twice instead of the FOLDOC fixed-point definition -- could you
repost, please?
--
http://www.kynosarges.de
Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Christoph Nahr <Click here to reveal e-mail address> wrote:
[Original message clipped]

Doh, yes. The FOLDOC fixed-point definition is:

<quote>
A number representation scheme where a number R is represented by an
integer N such that R=N*B, where B is the (assumed) base of the
representation.
</quote>

I don't believe that applies to Decimal, despite the documentation.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Christoph Nahr
On Sat, 21 Aug 2004 16:18:12 +0100, Jon Skeet [C# MVP]
<Click here to reveal e-mail address> wrote:

>I don't believe that applies to Decimal, despite the documentation.

I think you're right. The ECMA standards for C# and the CLI make no
mention of Decimal being a fixed-point format, although they oddly
reserve the term "floating-point" for Single/Double.

The term "fixed-point" only comes up in that one MSDN sentence, and
that's apparently a mistake. Decimal certainly looks like a floating-
point format that can accurately represent decimal fractions.
--
http://www.kynosarges.de
Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Christoph Nahr <Click here to reveal e-mail address> wrote:
[Original message clipped]

Yes, I noticed that. Very odd.

[Original message clipped]

Well I'm glad to know that if I'm going crazy, I'm not the only one :)

I'll try to get some word from MS on this...

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Chris Taylor
Hi,

Interesting. I believe the .NET definition is also not consistent with
Microsoft's own earlier definition. I believe the .NET decimal
implementation is based on the Oleaut32.dll implementation so I took a look
at the MSDN definition for DECIMAL, I quote that definition here:

<definition name="DECIMAL" source="MSDN">
A decimal data type that provides a sign and scale for a number (as in
coordinates). Decimal variables are stored as 96-bit (12-byte) unsigned
integers scaled by a variable power of 10. The power of 10 scaling factor
specifies the number of digits to the right of the decimal point, and ranges
from 0 to 28.
</definition>

This seems to be a more reasonable definition?

Cheers

--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor

"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Chris Taylor <Click here to reveal e-mail address> wrote:
[Original message clipped]

That's equivalent to the one given in System.Decimal though - the bit
that says:

<quote>
The binary representation of an instance of Decimal consists of a 1-bit
sign, a 96-bit integer number, and a scaling factor used to divide the
96-bit integer and specify what portion of it is a decimal fraction.
The scaling factor is implicitly the number 10, raised to an exponent
ranging from 0 to 28.
</quote>

Both of those are fine, I think - it's the calim that it's a fixed-
point type that I have issues with.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Jay B. Harlow [MVP - Outlook] (VIP)
Jon,
Continuing my other post:

If a Decimal is simply a scaled Integer (as opposed to floating point which
would be a scaled "fraction" by my earlier thought).

That might explain (to me at least) how the Decimal class remembers trailing
zeros.

1000.00 is stored as 100000 e-2.

Just a thought
Jay

"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Jay B. Harlow [MVP - Outlook] <Click here to reveal e-mail address> wrote:
[Original message clipped]

Well, they're both scaled integers from one point of view - it just
depends on how much you scale them by (i.e. whether you include the
size of the mantissa in the exponent or not).

[Original message clipped]

The only reason that can't be done in floating binary point (as
specified by IEEE 754) is normalisation, I think - the assumed 1 on the
front of the fraction. I could easily be wrong, however - I'm rather
tired at the minute :(

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Jay B. Harlow [MVP - Outlook] (VIP)
Jon,
I agree its confusing.

I thought floating point numbers (Single/Double) have the entire number to
the right of the decimal point (1.xyz) with an implied 1 where as fixed
point (Decimal) has the entire number to the left of the decimal point
(xyz.) (ala Integer).

For example the number 123 is:

1.23 E2 in (base 10) floating point, while its 123 E0 in decimal

Basically its how the scale is represented.

I thought Decimal was Fixed point because the decimal point is all the way
on the right just like Integer. Then that number is scaled.

If that made any sense...

Jay

"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Jay B. Harlow [MVP - Outlook] <Click here to reveal e-mail address> wrote:
[Original message clipped]

No, floating-point just means that the location of the point is
specified by the value, whereas fixed-point means that the scaling
factor is specified by the type itself. For instance, you could have a
fixed-point representation which *always* has exactly two digits to the
right of the decimal point.

Indeed, this is how the Numeric type in SQL works - you specify the
scale and the precision of the number when defining the column, and you
always know how many decimal places there will be.

[Original message clipped]

That's just a bias though - work out how long the mantissa is, add or
subtract the appropriate number of powers, and there's no difference.

Imagine that all decimal numbers were of the form

0.xxx

and that the scaling factor is the same minus 28 or 29. That might
work. I think. Possibly they *are* fundamentally different - but I
think they're both *floating* point because the position of the point
is specified by the value rather than the type itself.

[Original message clipped]

Binary floating point is exactly the same as that though - you take a
binary integer, optionally (depending on other things) add a leading 1,
and then scale it by an amount specified by the exponent part.

The Decimal type admittedly doesn't have the leading digit implied
(because it can't), but they're the same principal otherwise, just with
a different base and with different ranges of values. (Decimal also
doesn't have the various things like NaN, infinity, denormal/subnormal,
but that's a different matter.)

I could be wrong about some of this - I'm currently somewhat shattered
- but I *think* that's about right.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
    
Jay B. Harlow [MVP - Outlook] (VIP)
Jon,
Unfortunately I did not explain my self very well :-(

Unfortunately I do not know how to explain it better. :-((

The reason I consider Single & Double floating point is the normalization
with the implied 1.

The reason I consider Decimal fixed point is the lack of normalization with
the implied 1.

Note I also consider Decimal a floating point number for the reason you
gave, I hope you agree its just not an IEEE floating point number.

I see it as overlapping circles where Single & Double are in the floating
point circle & the IEEE floating point circle, where are System.Decimal is
in the floating point circle & the fixed point circle. While Integer is only
in the fixed point circle. Note, I consider SQL's numeric to be in a circle
very similar to Decimal's circles but definitely not floating point.

Maybe it would be more accurate to state I consider Decimal a scaled
Integer. Ergo fixed point like.

Jay

"Jon Skeet [C# MVP]" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
 
    
Jon Skeet [C# MVP] (VIP)
Jay B. Harlow [MVP - Outlook] <Click here to reveal e-mail address> wrote:
[Original message clipped]

Surely the types would be called "normalised" and "non-normalised" in
that case, wouldn't they? To me, the name suggests the meaning very
closely.

[Original message clipped]

It's certainly not an IEEE 754 floating point number - it couldn't be,
as IEEE 754 only specifies binary floating point numbers in the first
place :) I don't know whether there's an IEEE standard for decimal
floating point numbers, and if there is, I don't know if System.Decimal
conforms to it :)

[Original message clipped]

No, decimal *isn't* in the fixed-point circle, because its point isn't
fixed. Fixed and floating point are mutually exclusive, IMO. (Note that
FOLDOC includes "Opposite: fixed-point" in its definition of floating-
point.)

[Original message clipped]

SQL's numeric is in the fixed-point circle, definitely.

[Original message clipped]

But "fixed point like" isn't to do with whether it's a scaled integer
or not - it's to do with whether that scaling factor is fixed (hence
the name) or not. At least, that's how I see it.

--
Jon Skeet - <Click here to reveal e-mail address>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Reply to this message...
 
 
System.Console
System.Decimal
System.Double
System.Math
System.Single
System.String




ExamGuru IT Solutions - .Net Guru is owned and operated by ExamGuru, Inc., the man behind .Net Guru. If you're in the market for bespoke software or software consultancy, why not get him and his highly trained team to help? - www.examguru.net/ITCertification
Ad


Need Dot Net Interview Questions?
Ask ExamGuru, Inc. for advice and help on Passing .Net Interviews
.Net Projects
Best-of-breed application framework for .NET projects, developed by ExamGuru, Inc. and ExamGuru IT
Free .net Help
Commission ExamGuru, Inc. and his team for your next bespoke software project
FogBUGZ
The only bug tracking system carefully crafted with one goal in mind: helping teams create great software.
Awesome Tools
If you don't know about these, you're missing out... IT Certification Questions
IT Interview Questions
Free Oracle 10g Training
MCSE Boortcamp
Cisco Study Guides
Cheap Study Guides
Exact Questions
Dot Net Interview Questions
Oracle OCP
Cheap Travel
Designer Perfumes - Wholesale Prices
Free Programming Tutorials
 
ExamGuru IT Solutions - .Net Guru is owned and operated by ExamGuru, Inc., the man behind .Net Guru. If you're in the market for bespoke software or software consultancy, why not get him and his highly trained team to help? - www.examguru.net/ITCertification
 Copyright © ExamGuru, Inc. 2001-2006
Contact Us - Terms of Use - Privacy Policy - www.dot-net-guru.com - www.examguru.net - www.oraclesource.net - www.itinterviews.net - www.examguru.net/ITCertification