views:

549

answers:

12

I want to store a number with the following 0.000 which is the best data type to use.

A double?

Also I guess an INT is just out of the question?

A: 

Float would be better.

Braveyard
+2  A: 

float is 7 digits precision. double is 15 digits precision.

so float would be more than enough

Yassir
+2  A: 

My advice is, use float. For more precision use double and for even more precision use decimal.

mnn
The first who suggest Decimal! :-)
Workshop Alex
A: 

If it's for file size you can change the size from kilobyte to byte or from a smaller range (meg to kb) and be without any floating and keeping the same precision.

Otherwise, double would be good.

Daok
+3  A: 

Based on your comment that yopu are representing file size, consider storing bytes in integer or long integer... This avoids your problem completely, avoids rounding errors inherent in converting 1/1024th of a KB to a double or float and has advantedge of being closer to the real-world measurement you are representing.

Charles Bretana
Since file sizes are going to be integers, a big integer is ideal. I don't think we currently have to worry about hard drives larger than a 64-bit int can capture. Having said that, if we want to do math on the number to boil it down to K, M, G, etc, then decimal is ideal.
Steven Sudit
+6  A: 

I'm still a fan of decimal, it may take a bit more space but doesn't have quite the same rounding errors float and double have.

It really depends upon what sort of precision and accuracy you need and the types of numbers you expect to store.

Such as if you're working with money, then the rounding errors in float or real will probably be unacceptable anyway.

Of course, if its completely fixed, depending upon the range of values required, you can just multiply by 1000 and store as an integer type such as short.

An example rounding error from http://www.yoda.arachsys.com/csharp/floatingpoint.html

double a = 0.65d;  
double b = 0.05d;  
Console.WriteLine("{0:r}", a + b);

Note, the {0:r} is important when printing otherwise .net will round the value and it will be displayed as 0.7 even though its not exactly 0.7.

Over several computations such rounding errors can be increased.

KeeperOfTheSoul
Can you give an example of a rounding error that would be significantly important?
Daniel T.
I've added an example to the answer.
KeeperOfTheSoul
Also, try this out for a bit of fun: (float)(16777216f + 1) == 16777216f should return true
KeeperOfTheSoul
and if you want a really confusing infinite loop: for (float f = 16777216f; f < 16777217f; f++) { }
KeeperOfTheSoul
+22  A: 

The decimal type is the best for fixed point math.

From the C# Spec Section 4.1.7:

Contrary to the float and double data types, decimal fractional numbers such as 0.1 can be represented exactly in the decimal representation. In the float and double representations, such numbers are often infinite fractions, making those representations more prone to round-off errors.

Matt Brunell
totally agree.
dotjoe
Decimal data type rocks.
Matthew Ruston
And the only type that can handle fractions but still guarantee that 1 + 1 is EXACTLY 2.
Steven Sudit
Yes, but it is even bigger than Double, JL wants to save on filesize.
Henk Holterman
For a software that manage currency, precision and consistency are more important than the file size.
Pierre-Alain Vigeant
Well, `(1.0f + 1.0f == 2.0f)` still holds, problems start when you get to `(1.3f + 1.5f != 1.8f)`...
Pavel Minaev
A: 

A float is "accurate" to about 6 decimal places, and a double is "accurate" to much higher precision. However, neither of them can accurately represent every 3-decimal-place value.

Chances are you will be fine using a float, as long as you don't mind a number like 0.123 to be stored as 0.122999999... a bit of careful rounding should be enough to achieve what you want.

If you want to exactly represent all the possible 3-decimal-place fractions, you would be better off using an integer and multiply the values by 1000. i.e. a value of 3.456 would be stored in the integer as 3456.

Jason Williams
+4  A: 

If you are dealing with decimal numbers, and your specification requires exact precision for N decimal places, then your only options are decimal, or int/long with manual scaling (i.e. multiply and divide by 1000 as needed when doing input/output and arithmetic). The latter is faster and has more compact representation, the former is slower and wider, but code is shorter and clearer. Of course, you can also encapsulate all the fixed-point boilerplate code in your own struct which uses int/long under the hood.

Do not use float or double. They cannot represent many decimal fractions exactly. You can get away with it if you always round consistently, but as soon as you start doing arithmetics or comparisons, this may (and usually will) trip you, because rounding errors accumulate.

Pavel Minaev
They also can't represent certain integral numbers either.
KeeperOfTheSoul
Er, what _integral_ numbers they cannot represent (aside from values out of range of the type)? Integral is by definition a number without a fractional part... Do you perhaps mean _fractional_ numbers? Yes, a `Decimal` cannot represent `1/3` precisely. However, the question is very specific - he needs to reprecent _decimal_ fractions with a precision specified in a number of _decimal_ places. Thus, representing `1/3` as `0.333` is the desired behavior.
Pavel Minaev
A: 

Do you want to store the number this way, or present it? Store with the greatest precision you can and format it to #.000. Storing your numbers isn't likely to be a storage problem, so go ahead and use something that is too big.

As noted integers can be appropriate for things that can be reduced to integer values. (display GB, store bytes as int or bigint; display days, store seconds as bigint)

Precipitous
A: 

For file size, which seems to be what you wish to store, use a long (Int64) to store the number of bytes. Or use an int if you know files will be less than around 2GB. You can then convert this to a more human readable form using a simple method.

Dan Diplo
+1  A: 

Int is perfect for you. You'll waste memory with decimal, and if you use ONLY 3 decimal places, you can allways remember to multiply/divide by 1000.

Anyway, that can be tiresome if you use it for financials - then stick with decimal anyway.

If you use it for some kind of a units, like duration or lenght, int will suit just fine for you, because you can allways go from seconds to milliseconds, or from meter to millimeter.

It would be helpfull if you explained the desired use for it.

Also, from the info I see at the MSDN, decimal is just like the floating point, but with more precision and without rounding.

Further: decimal - 16 bytes, int - 4 bytes

Howevery, your int divided by 1000 will have range of only +/-2,147,483

EDIT:

I read your comment and you want to use if for filesize? If so, I don't see where do decimals come from... Maybe they are only for the purpose of displaying?

Anyway, go with Int64 here.

Daniel Mošmondor