8

The code here is straight forward but I don't understand the results:

float percent = 0.69f;
int firstInt = (int)(percent*100f);

float tempFloat = percent*100f;
int secondInt = (int)tempFloat;

Debug.Log(firstInt + " " + secondInt);

Why is firstInt 68 but secondInt is 69?

Foggzie
  • 9,691
  • 1
  • 31
  • 48
  • https://dotnetfiddle.net/YMJExy - result is `69 69`.. – Blorgbeard Aug 08 '16 at 23:05
  • Local machine, I get the `68 69` result. – jdphenix Aug 08 '16 at 23:05
  • It looks like `69` can't be accurately represented by a float and actually comes out to something like 68.999999... Changing your second line of code to `int firstInt = (int)Math.Ceiling(percent*100f);` gives you 69. No idea why assigning that 68.99999... to a float variable "corrects" the problem though. – itsme86 Aug 08 '16 at 23:05
  • On my local machine, I get `68 68` with optimizations enabled, and `68 69` without. Weird. – Blorgbeard Aug 08 '16 at 23:07
  • @Blorgbeard Same here. VS 2015. Targeting framework 4.6.1. – itsme86 Aug 08 '16 at 23:10
  • 1
    Here's an answer from Mr. Lippert: http://stackoverflow.com/a/8795656/1141432 – itsme86 Aug 08 '16 at 23:18

1 Answers1

1

It looks like the compiler has figured out the value of the

percent*100f

expression using double math, and optimized away the computation. This is not allowed when intermediate results are saved in a float variable.

Since .69 does not have anexact representation in float or in double, the two representations "land" on different sides of an int: double is slightly above, while float is slightly below the actual value of .69.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • This does seem to be a possible correct answer, I'm surpirsed that the compiler thinks a reasonable optimisation for a `float` calculation is to do it as a `double` though. When it's just blatantly changing the output and there are no hardware (runtime) considerations to be made since it's just plonking the value in the output. Do you know why it does this? – starlight54 Aug 08 '16 at 23:22
  • Ah no worries, the answer to my question is in the other answers from the comments, the C# compiler can pretty much use more precision whenever it likes if given the option, as you say, storing it as a `float` prevents it from doing that. – starlight54 Aug 08 '16 at 23:29