Jump to content
  • Advertisement

Recommended Posts

int i = 208;

float f = (float)i;

 

Despite i know you will rant about that code please tell me if i will be 208 or i may get something close to 208?

 

Cheers

Edited by WiredCat
Semantics

Share this post


Link to post
Share on other sites
Advertisement

For whole numbers that are sufficiently close to zero, you will get the exact number, i.e. 208.0 in this case.

Share this post


Link to post
Share on other sites

To my knowledge, although I could be wrong in some contexts (I'm no expert), you should never check for exact values when dealing with floating point values - always check for ranges. Why is this relevant, you might ask? Because if what I said is true, then whether or not (float)i returns exactly 208.0... should be completely uninteresting to you.

(Since your question was already answered, I thought I'd just respond to a possible reason why you asked it, to begin with.)

Edited by Madolite

Share this post


Link to post
Share on other sites
On 11/21/2017 at 3:57 PM, Madolite said:

To my knowledge, although I could be wrong in some contexts (I'm no expert), you should ...

32-bit floating point numbers, called "float" in C, C++, C#, and various other languages, can accurately represent 23 bits of precision, plus another bit for sign. So they should work with any number from +/- 2^23, or about 8.38 million to -8.38 million.

Converting from base ten to floating point and back to base ten is only guaranteed for 6 decimal digits precision, although it should work up to that range of 8.38. Beyond that it cannot fit exactly within those 23 bits.  That conversion applies just as much to 7654321 as it does to 0.007654321 or 765432100000000. 

As for the range, there is a must-read article, "What Every Computer Scientist Should Know About Floating-Point Arithmetic" which explains how it works, why it works, how certain calculations are troublesome, catastrophic cancellation where your result is garbage, and more.  It requires a bit of math to understand, but it allows you to be far more precise in how much error you've accumulated from various sources, instead of the handwaving answer like "just check within 0.001 or something".

Share this post


Link to post
Share on other sites
8 hours ago, frob said:

Converting *snip* back to base ten is only guaranteed for 6 decimal digits precision.

I know about the accuracy of floating point numbers, but I didn't realize it went both ways. So using an int cast isn't always accurate and you need to explicitly truncate or w/e beforehand, and then cast it? I thought casting from "more complex to less complex" automatically truncated a value?

Edit: I asked about it on Discord and yeah, seems like casts aren't always just reading the presented float value (in code), but rather the actual bit value (like when embedding or doing other funky stuff across systems). Which could make weird things happen for sure. So 280.00 could become 279 when cast to an int (well maybe not 280.00 in particular, but some equivalent value with less casting accuracy, I'm sure you get my point).

Thanks, I had no idea. :D Either way, as said, one should never assume that floats are exactly the value that we see, unless we know it otherwise. So checking range seems like the way to go (at least most of the time).

Edited by Madolite

Share this post


Link to post
Share on other sites

Any integer from 0 to 16777216 (2^24) inclusive (and the negative version of that range) can make a round-trip between 32-bit int and 32-bit float without any wacky changes happening.

Between 16777216 (2^22) and 33554432 (2^25), floats can only store integers that are a multiple of two (even numbers). Any odd number that you cast back and forth will be rounded to the nearest multiple of two.

Between 33554432 (2^25) and 67108864 (2^26), floats can only store integers that are a multiple of four....

 

Between 8388608 (2^23) and 16777216 (2^24), floats can now only store integers -- you get no decimal places!

Between 4194304 (2^22) and 8388608 (2^23), floats can only store two possible fractional parts: ".0f" or ".5f"

Between 2097152 (2^21) and 4194304 (2^22), floats can only store four possible fractional parts: ".0f", ".25f", ".5f" or ".75f"....

Share this post


Link to post
Share on other sites
2 hours ago, Madolite said:

So 280.00 could become 279 when cast to an int (well maybe not 280.00 in particular, but some equivalent value with less casting accuracy, I'm sure you get my point).

No, that should not.  If it is exactly 280 it should cast to an int as 280. 

If it is not 280, but instead a value like 279.9996 that your tools silently rounded up, then the value is truncated to 279.  But that is only because your value is not what you thought it was.

Similarly if the value is slightly more than 280, such as 280.0001, it will truncate to 280 even though that isn't the value.

Go read "What Every Computer Scientist Should Know About Floating-Point Arithmetic". You seem to need it.

Share this post


Link to post
Share on other sites
11 hours ago, frob said:

"If you can't explain something in simple terms, you haven't understood it well enough." - Albert Einstein

I know full well the ranges of floats and doubles. My mistake was assuming that IEE754 is the only standard of determining floating point ranges, which the guys on Discord reassured me was wrong. And yes, your article bring that up as well, to some extent, but do you really need people to read that entire article just to get that simple concept clarified? The other guys on Discord seemed to have no problems answering this in 5 seconds, once they identified the question (which I know I can be bad at, sometimes, so don't worry).

But I'm certainly not an idiot, nor did you ever say as such, but you certainly seem to implied it, through your reply. And fastcall22 and matt77hias both mentioned IEE754 as well, and I don't see you replying to and correcting them for assuming that IEE754 was in place here.
 

11 hours ago, frob said:

No, that should not.  If it is exactly 280 it should cast to an int as 280.

Then what is your issue with my comment? Feel free to explain why specifically you thought I didn't understand basic floating point arithmetic that most people who care are able to google in 10 seconds, so I know how to phrase myself in the future.

There seems to be something seriously NOT COOL going on here, between you and me, right now. And I'd like to get to the bottom of it. Perhaps in PM, if necessary.

Edited by Madolite

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!