-4

So, here comes a repeated question:

In one of my client's machine, i have this code,

        public double getFreeSpace()
        {
            return this.totalSize - this.listElements.Sum();
        }

and when subtraction like this happens: (1.0 - 0.8) the expected result is (0.2) but she gets the result some thing as 0.199999.

While this is not the intended result, how to get 0.2 as output for this code?

The stackoverflow question here, discusses the same issue but suggests using decimal as the alternative. (But, also note that in the same answer, we get a warning : It is a 128 bit datatype as opposed to 64 bit which is the size of a double).

I also tried, Math.Round(1.0-0.8, 0, MidpointRounding.AwayFromZero) but this does not do the job.

The question now is, how to get the desired answer as 0.2 while still keeping the same datatype as double without using a decimal ?

Community
  • 1
  • 1
  • 2
    Without using decimal, you can't express 0.2 exactly. You can alter how you display it afterwards though. What do you plan to do with the output? – Baldrick Nov 18 '13 at 06:35
  • 3
    Q: The question now is, how to get the desired answer as 0.2 while still keeping the same datatype as double? A: Learn how floating point numbers work: http://effbot.org/pyfaq/why-are-floating-point-calculations-so-inaccurate.htm – paulsm4 Nov 18 '13 at 06:36
  • -1: Very unclear what you did not understand from linked question. It clearly says "... It also doesn't allow for an exact representation of the number 0.2..." with plenty of links with explanations/deep technical details. This question may be ok if you show what you don't understand. – Alexei Levenkov Nov 18 '13 at 06:41
  • @Baldrick: Its an comparison case. Just to check if the given item (0.2) is less than or equals to (1.0-0.8). But, since this (1.0-0.8) does not show (0.2) the comparison fuct fails (0.19999) and thats why. – now he who must not be named. Nov 18 '13 at 06:41
  • I can't see the problem with using decimal. Are you extremely short of memory / CPU time? I can't invisage a scenario where a getFreeSpace check would need be so performance / memory critical – Baldrick Nov 18 '13 at 06:44
  • @Baldrick: I am just trying to be `most-optimal`. Though there is nothing that is `extremely short of memory or CPU time`, i just wanted to code optimally from the beginning itself. – now he who must not be named. Nov 18 '13 at 06:47
  • @paulsm4, Alexei: thanks for the inputs. Yes, you guys are correct. I ll first have to understand how its works from the links in the linked questoin and from `effbot.org` links. Thanks for guiding through. Will take a look. :) – now he who must not be named. Nov 18 '13 at 06:49
  • 2
    Trying to be over-optimal from the start is called 'premature optimization', and it is actually a very bad idea. It leads to confusing overly complex code which is hard to maintain. Code for clarity and simplicity, profile for performance, and optimize only the slow bits. Anyone looking at your code in 6 months time will thank you (including yourself!). – Baldrick Nov 18 '13 at 06:50
  • @Baldrick: thanks for the comment. So, using `decimal` does seem `OK` with my case. Will go with that. thanks. – now he who must not be named. Nov 18 '13 at 06:51
  • 1
    @Baldrick: Selecting data types and algorithms suitable for the desired computation is not premature optimization. – Eric Postpischil Nov 18 '13 at 09:31
  • @Eric Postpischil: I agree that it's not necessarily premature optimization - but in evaluating 'suitable' there are more considerations than just performance. It's not unreasonable to suggest that simplicity should be an important consideration unless there's reason to think an area of code is likely to be a bottleneck. As with most things, there's a balance to strike. Avoiding decimal here for purely for performance reasons would seem of doubtful benefit in this case. – Baldrick Nov 18 '13 at 09:39

1 Answers1

1

If the question is

how to get the desired answer as 0.2 while still keeping the same datatype as double without using a decimal

then the answer is: you can't.

I think you should take a look here to get some extra information.

The need for accuracy was the reason why the decimal type has been created. These types are slower to work with but are more accurate.

Community
  • 1
  • 1
MBender
  • 5,395
  • 1
  • 42
  • 69
  • 2
    " It all stems from the fact that 1 byte is 8 bits" -er, no it doesn't! It's due to representation in a given base. – Mitch Wheat Nov 18 '13 at 06:47
  • 1
    The answer "you can't" is correct. The reasoning as to why is completely false. – Mitch Wheat Nov 18 '13 at 07:16
  • @MitchWheat Point taken and I've changed the answer, but... isn't using said base the result of those 8 bits per byte? – MBender Nov 18 '13 at 07:20
  • @Shaamaan No. `Float`s are stored in a binary format, or base 2 for efficiency. `Decimals` are stored in a decimal format, or base 10, for decimal accuracy. None of this has anything to with the number of bits in a byte. – Rik Nov 18 '13 at 07:48
  • @Rik Dammit. I could have sworn... oh well. *note to self* Do not add theory to answers and stick to practise, you're better at it. *end note to self* – MBender Nov 18 '13 at 08:02
  • @Shaamaan Or, you know, make a mistake every now and then, and learn from it. :) – Rik Nov 18 '13 at 08:09
  • 1
    `decimal` is not more accurate than binary floating point. It merely has different errors. Those include errors when dividing by most numbers (converting annual rates to monthly, converting currencies, calculating unit price of a three-for-one deal, and so on) and when calculating scientific functions (sine, logarithm, and so on). **Every** numerical arithmetic system has errors. – Eric Postpischil Nov 18 '13 at 09:37