Why is the data stored in a Float datatype considered to be an approximate value?

风格不统一 提交于 2019-12-12 18:09:35

问题


I've never understood why a float datatype is considered an approximation while a decimal datatype is considered exact. I'm looking for a good explanation, thanks.


回答1:


well, you're right - it's misleading to make such a blanket statement. to understand completely you need to grasp two things.

first, decimal is intended for storing (exactly) decimal values with a fixed number of decimal places. typically, money (where the decimals are cents, for example). that's a very specific use case. it's not an exact store for any value; it's only for decimal values with a fixed number of decimal points, and the implementation is tailored to do that correctly.

second, floats are intended to be a more general datatype - they are used to store "any" value - and the implementation reflects that (so, for example, the implementation aims to cover a wide range of scales and support operations as efficiently as possible). in particular, it uses a binary representation that cannot represent all decimal values exactly. so, for example, it can store 0.5 exactly, but it can't store 0.1 exactly. that's just a fact of life of the binary - base 2 - representation used, but it means that for money, floats are not a good idea: if you can't store 0.10 exactly as a float then any calculations involving 10 cents may accumulate unexpected errors.

in other words, both have their limitations. the only way that decimal is "more exact" than float is that it's easier to understand: the values for which it does work exactly are clearly defined, useful, and match the "natural" base 10 representation we use. in contrast, it's much harder to understand which values will be stored exactly by floats, and which not, because they depend on the underlying base 2 representation.




回答2:


Well, it depends on your point of view. Both float and decimal (assuming you mean types like the ones in C#) represent exact values. However, in both cases conversions (and arithmetic) can end up with approximations where the value stored is only "the closest one available to the theoretical exact value".

In particular - and importantly the normal cause of the "float is approximate" idea - is conversions of literal values in code:

float f = 0.1f;
decimal d = 0.1m;

These literals are expressed in terms of decimal numbers - and 0.1 can't be exactly represented as a binary floating point number. However, it can be represented exactly as a decimal floating point number.

If we used binary for literals, e.g.

// Imaginary syntax - doesn't work in C#!
float f = 0b0.11f;

then there wouldn't be any approximation here - that value would be exactly the same as the decimal value 0.75.

Basically it's all about the bias of humans to think about numbers in base 10. From the point of view of an alien with 3 fingers on a single hand who represented values in base 3 naturally, both float and decimal would be "approximations".

(There are other significant differences between float and decimal in C# around the significant digits vs the range of values, but that's a different matter.)




回答3:


You can get all the gory details here, but basically IEEE floating point stores numbers as an integer mantissa times two raised to an integer power. Just like some fractions like one-third cannot be expressed exactly as a non-repeating base 10 decimal number, many fractions cannot be expressed exactly as binary fractions. This is often surprising because, while were used to 1/3 as a repeating decimal we intuitively expect 1/5 to be easily represented as 0.2, but in binary it's a repeating decimal (binarial?) that cannot be exactly represented in a finite number of bits.




回答4:


A decimal value is exactly equal to the value of its string representation (edit: in decimal, as Skeet notes), and decimal is also capable of exactly representing decimal numbers with a limited amount of digits. On the other hand, a float value often will differ from its string representation, and there are many decimal numbers (such as 0.1) that cannot be exactly represented as a float.



来源:https://stackoverflow.com/questions/7372670/why-is-the-data-stored-in-a-float-datatype-considered-to-be-an-approximate-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!