-2

So for some reason I have a float named wday which has the value of 7.000000, but when I say

int wdaygiven = wday;

I get 6 and not 7. This also happens when I do this

NSNumber *num = [NSNumber numberWithFloat:wday];

Any ideas why? I really need 7 as the value given and not 6.

Thanks in advance

isklikas
  • 190
  • 2
  • 16
  • How was this given to you as a `float`? Can you fix that problem upstream? In my current job, I deal with code that uses Java `String`s instead of `Date`s, so I feel your pain. – Eric Jablow Jun 16 '13 at 13:00
  • That happens because it is floating-point. – Hot Licks Jun 16 '13 at 13:39
  • possible duplicate of [strange output in comparison of float with float literal](http://stackoverflow.com/questions/1839422/strange-output-in-comparison-of-float-with-float-literal) – Hot Licks Jun 16 '13 at 13:39
  • 3
    7.0 is exactly representable as a float, and if the value were set directly there would be zero rounding error. If it is not 7, it is because of how it was calculated. – Patricia Shanahan Jun 16 '13 at 14:07
  • @HotLicks no it is not a duplicate, the issue in the other question was that he was treating his float as a double, mine issue was that the float occured through a logarithm calculation which occured through a change of base. The change of base made the value infinitely close to what I wanted but not precise enough. Mine issue was solved by using the ceilf method, so please unmark it as duplicate it is a completely different case :) – isklikas Jun 16 '13 at 14:25
  • @isklikas I do not think you are using the phrase “infinitely close” properly. – Pascal Cuoq Jun 16 '13 at 17:10
  • 1
    @isklikas - It's still a dupe. Floating point numbers are not exact. As has been stated here about weekly, in the other dupes of your question. – Hot Licks Jun 16 '13 at 18:55
  • possible duplicate of [Strange behavior when casting a float to int](http://stackoverflow.com/questions/8911440/strange-behavior-when-casting-a-float-to-int-in-c-sharp) – jscs Jun 16 '13 at 19:02
  • @HotLicks: Floating-point numbers are exact. Floating-point operations might or might not be. – Eric Postpischil Jun 16 '13 at 21:10
  • 1
    @EricPostpischil - I'll concede that point on a technicality, but it's of little practical value. One should assume, unless positively proven to the contrary, that a floating point number does not reflect the exact value of the mathematical expression that produced it. – Hot Licks Jun 16 '13 at 23:21
  • @HotLicks: The practical value is that knowing what is exact and where the errors come from, and how big they can be, allows you to start designing software to avoid or limit errors and to write proofs about them. – Eric Postpischil Jun 17 '13 at 02:27
  • @PascalCuoq Well mathematically speaking, a change of base creates a result that is infinitely close with the value wanted, but not exactly the same, as you will never get exactly 7 (or any other number). Now in programming this phrase might be wrong, but mathematically speaking it is the right phrase to use. – isklikas Jun 18 '13 at 10:25
  • @isklikas No, the sequence of words “infinitely close” does not make sense mathematically, because the only sense this phrase could have would be the same as “equal” (otherwise, the two values would not be **infinitely** close). And of course it does not make sense for floating-point numbers either, which are either equal or differ by at least one ULP, a **finite** value. – Pascal Cuoq Jun 18 '13 at 13:26

2 Answers2

1

It's probably because the value isn't exact 7, but something like 6.999... (lots of 9) which appears to be 7. If converting to int, all decimals are cut and it results in 6.

Depending on your application you could round, take the next greater int, add 0.1 and convert to int a.s.o.

JeffRSon
  • 10,404
  • 4
  • 26
  • 51
  • Yes that was the issue, I was dealing with logarithms on base 2, so the change of base with 10 to create a logarithm base 2 obviously gave a value which is infinitely close to 7. Using `int wdaygiven = ceilf(wday);` solved the issue. Thank you so much! – isklikas Jun 16 '13 at 13:37
  • @isklikas - You still don't understand. Except in a few special cases, floating-point numbers are *never* exact. Any time you assume they're exact you're making the same error, regardless of the particular computation that led to the number. – Hot Licks Jun 16 '13 at 18:56
  • @isklikas: Why is taking the ceiling the right solution, versus rounding? Do you know that the same calculations which yield something slightly under 7 when 7 is desired will not also yield something slightly greater than 5 when 5 is desired? – Eric Postpischil Jun 16 '13 at 21:11
  • Yep, arbitrarily taking the ceiling is not the right answer. Better by far to do some sort of rounding. – Hot Licks Jun 17 '13 at 10:52
  • @HotLicks Well normally yes, but in my case where a logarithm with a change of base is used, it is always the case that the value will be slightly below the wanted, because change of base can't be 100% precise. Now, because it is always a bit lower, ceilf(wday); solved the problem and it is working perfectly now. – isklikas Jun 18 '13 at 10:22
  • @isklikas - If that's what you choose to believe, go ahead. – Hot Licks Jun 18 '13 at 10:50
  • @HotLicks Oh I am sorry if I sounded arrogant and this is not my intention and you would probably be right if I was dealing with a broad range of numbers, but the only numbers that can come out of my equations are 1, 2, 3, 4, 5, 6, or 7. Since all of them come correctly when needed then ceilf(wday); works perfectly, so there is no need for a different method. Thank you though for your interest, it's appreciated! – isklikas Jun 18 '13 at 12:33
0

float value wday=7.00000 maybe less than 7.

Use this:

int wdaygiven = roundf(wday);
  • No, `float value wday=7.00000` may not set `wday` to a value lower than 7, although `float value wday=` may. – Pascal Cuoq Jun 16 '13 at 17:12
  • @PascalCuoq You are right. However, "So for some reason I have a float named wday which has the value of 7.000000", 7.000000 maybe is a mathematical result. – matrix chen Jun 20 '13 at 03:12