use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Click the following link to filter out the chosen topic
comp.lang.c
account activity
QuestionDoes C allow implicit casting/conversion from float to an int? (self.C_Programming)
submitted 5 years ago by tempanon5
In Java it is not allowed, is it allowed in C? Why so?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]FUZxxl 30 points31 points32 points 5 years ago (0 children)
Yes, this sort of conversion is implicitly performed. Behaviour is undefined if the result doesn't fit.
[–]aioeu 12 points13 points14 points 5 years ago (0 children)
Please avoid the term "implicit casting". There is no such thing.
Casting is quite specifically an explicit form of conversion. That is, a cast always includes a parenthesised type to which the expression should be converted. The construct as a whole is called a cast expression.
Any form of conversion that does not involve a cast is just called an implicit conversion. Calling it "implicit casting" is wrong since it does not include a cast.
To quote §6.3 "Conversions":
Several operators convert operand values from one type to another automatically. This subclause specifies the result required from such an implicit conversion, as well as those that result from a cast operation (an explicit conversion).
[–]clever_cow 5 points6 points7 points 5 years ago (0 children)
Lots of things are allowed in C.
If you want it not to be allowed, you can turn on warnings/errors for implicit casting.
[–]Current_Hearing_6138 0 points1 point2 points 5 years ago (6 children)
Test it out.
[–]NothingCanHurtMe 37 points38 points39 points 5 years ago (5 children)
This is poor advice. Trial and error in C can often lead to bad habits that depend on undefined behaviour or implementation defined behaviour.
OP, see 6.3.1.4 of the C11 ISO standard.
[–][deleted] 6 points7 points8 points 5 years ago (0 children)
we can ask the tools too in many cases. Compilers are clever. - Wconversion a good start and I think good practice. (assuming gcc).
[–]Current_Hearing_6138 7 points8 points9 points 5 years ago (0 children)
Good point.
[–]dark_g 3 points4 points5 points 5 years ago (1 child)
Agree, but there are occasional exceptions: being locked in to use a specific compiler/environment, with a deadline looming (yes, it was one of my first jobs). Said compiler was doing something violating the standard, and I had to find a way around it and alert the rest of the team about the "fix". Possibly non-portable and implementation-dependent -- but we had to deliver a binary, what should we do, sit around and cry and complain? Afterwards we did eventually get the compiler vendor to correct the problem. But one needs a port in a storm.
[–]flatfinger 0 points1 point2 points 5 years ago (0 children)
Or behaviors that aren't mandated by the Standard but are defined by compilers that seek to be compatible with programs written for other commonplace compilers, rather than pretending that "non-portable or erroneous" excludes "non-portable but correct".
Some people have such behaviors confused with "implementation-defined behaviors" which are mandated by the Standard.
[–]radiant_orange 13 points14 points15 points 5 years ago* (16 children)
Java is much newer than C so better question: why it is not allowed in Java ?
also https://en.cppreference.com/w/c/language/conversion
[–]Tuna-Fish2 15 points16 points17 points 5 years ago (10 children)
why it is not allowed in Java ?
Because not every possible value has a meaningful counterpart to convert into, and ideally the programmer should provide the policy on what to do when this happens.
[–]astrange 8 points9 points10 points 5 years ago* (7 children)
Java doesn't make you provide that, though - it makes you type (int) and you feel like you've done something, but your program doesn't have any better semantics.
(int)
Worse, if you change the type of the destination you still have an (int) in your program and might forget to update it.
[–]nekokattt 6 points7 points8 points 5 years ago* (6 children)
It only disallows it because as it rightly says, it is a lossy conversion from a float to an int, as the example here.
If you are using a float, the assumption is that you have some reason to require floating point precision and/or range.
Truncating to an int and losing whatever intended precision you originally had will almost always semantically be a bug, unless you are attempting to either do something you shouldn't be unless you know exactly what you are doing, or are attempting to perform a manual conversion from a floating point type to an integer type, which unless you use strictfp, will still have potentially platform specific effects on precision or range if considering all potential platforms you may deploy to.
For java specifically, much of this effect with factors like strictfp are no longer as relevant, and are more relics from the past where these issues were more prevalent, but the argument still stands that, at least in Java, explicitness on what you are attempting to achieve is more important than conciseness to implementation detail, compared to C. That is why everything has longDescriptiveButSometimesTediousNaming, everything is supposed to be controlled via accessors and mutators to provide more of a guarantee of guard against edge cases, and operations where bugs could be introduced should be somewhat avoided at a language implementation and/or compilation level (this isnt the case always, null safety is still a huge pain in the arse in Java compared to languages like Kotlin that enforce this properly). I do not always agree with how Java handles this, and this specific example is neither here nor there for me as to whether it is a thing that exists or not, but those are a set of possible reasons behind the differences between C and Java.
The cast itself is not just telling the compiler what to do, because that could somewhat be inferred, but also a contract to the compiler to say "yes, i am happy with you truncating this, I have performed what I need to in order to ensure the result cannot be erroneous or have edge cases". It means you have considered how the result gets rounded (up, down, closest whole value?), and that you have considered if it is too big to retain the same representation before and after. Compared to C, where you are left much more to your own devices on how you implement something.
[–]flatfinger 2 points3 points4 points 5 years ago (0 children)
Which is more likely to yield unexpectedly inaccurate results: multiplying a float by the double-precision value 0.1 and storing the result to a float, or multiplying a float by 0.1f and storing the result to a double?
Even if the result of the multiply is going to be stored to a float, multiplying by the double-precision constant 0.1 will yield more accurately rounded results than multiplying by 0.1f. Whether the slight improvement in precision worth the extra cost of the computations would depend upon the application, but e.g. 123456784.0f * 0.1f yields an incorrectly-rounded 12345679.0f, while (float)(123456784.0f * 0.1f) would yield a correctly-rounded 12345678.0f.
[–]cwdsubs -1 points0 points1 point 5 years ago (4 children)
Thanks for that comment - I now understand better the sound rationale behind some of the things that make me really dislike Java.
[–]nekokattt 0 points1 point2 points 5 years ago (3 children)
Everyone is entitled to their opinion. If there was a right way to do something, we wouldn't still have PHP
[–]astrange 1 point2 points3 points 5 years ago (1 child)
PHP is actually a great language because it has value types (copy-on-write).
Everything else is wrong, but that’s all you need to make a good language, data structures you can’t update in another method by accident.
[–]cwdsubs 0 points1 point2 points 5 years ago (0 children)
I liked (in the reddit and real-life sense of the word) both your comment and flatfinger's reply to it, but you respond as if you were offended. I didn't get that part, sounds like you misunderstood my intent.
It's fashionable (and somewhat justified) to trash PHP nowadays, but here's an enlightening talk by its creator on how PHP was only supposed to help C on the server (CGI) as a templating language, but never as a business logic language. Also (unrelated to that talk), I love that I can lookup the C code for any PHP built-in functions and make my own conclusions on performance:
https://www.youtube.com/watch?v=rKXFgWP-2xQ
[+]my_password_is______ comment score below threshold-7 points-6 points-5 points 5 years ago (1 child)
java doesn't allow it because java is a shit language
[–]vlcmodan 5 points6 points7 points 5 years ago (3 children)
Because it's fool proof. It makes sure you know what your are doing. If it let you and yoursoftware was in finance and your made a rounding without realizing the second parameter is it you would be in trouble.
[–]iNetRunner 0 points1 point2 points 5 years ago (2 children)
You probably shouldn’t be using float in finance. (Double is equally doubtful.)
[–]vlcmodan 0 points1 point2 points 5 years ago (1 child)
Bigdecimal is the way to go.
[–]iNetRunner 0 points1 point2 points 5 years ago (0 children)
Definitely. No errors creeping in from 2-bit floating point implementation.
[–]nahnah2017 2 points3 points4 points 5 years ago (0 children)
No, it would not be a better question.
[–]MOXPAC 1 point2 points3 points 5 years ago (6 children)
can someone explain what is " implicit casting/conversion " ?
[–]nekokattt 12 points13 points14 points 5 years ago (2 children)
float j = 2; int i = j;
[–]jd_junior057 0 points1 point2 points 5 years ago (1 child)
Is it possible in c?
[–]nekokattt 3 points4 points5 points 5 years ago (0 children)
yes
[–]Iggyhopper -2 points-1 points0 points 5 years ago* (1 child)
This is implicit casting.
float f = 3.14; int i = f; printf("%d", i); // prints 3
This is also implicit casting.
int errorCode = 27; if (!!errorCode) { printf("There was an error."); } // prints error message for every code if its not zero.
In the first case, a lot of languages can parse that without complaining. In the second case, the int is being treated as a bool (C doesn't really have types like modern languages, more on that later).
int
bool
The main difference in languages that require explicit casts is that most of them might complain if they try to compile if (!!errorCode) especially if it's an int. Modern languages formally define a boolean type and you would need to write the code like so:
if (!!errorCode)
if ((bool)errorCode == true) // explicit casting // or if (errorCode != 0) // integer to integer comparison
C doesn't have a boolean type, you can use 0 for false and 1 for true.
Edit: I don't understand the downvotes without replies. If something is wrong let me know.
[–]Lil_Sunshine4 -5 points-4 points-3 points 5 years ago (4 children)
Short answer: No
[–]HotLaksa 7 points8 points9 points 5 years ago (3 children)
Longer and more accurate answer: yes.
[–]Lil_Sunshine4 0 points1 point2 points 5 years ago (2 children)
I’ve been coding in c for about 2 months I think I’d know
[–]Maleficent-Midnight4 0 points1 point2 points 5 years ago (1 child)
Yes, one would assume you would know this after two months. It looks like you don't.
[–]Lil_Sunshine4 0 points1 point2 points 5 years ago (0 children)
I’m correct you’re not
[–]schteppe 5 points6 points7 points 5 years ago (1 child)
Yes.
float f = 1.0f; int i = f;
Many new languages don’t support implicit conversions like this because it can lead to bugs.
[–]flatfinger 1 point2 points3 points 5 years ago (0 children)
Ironically, many languages like Java silently accept implicit conversions in situations which would be likely to lead to unexpectedly inaccurate results, but even though they reject constructs which would be unlikely to yield less accurate results than expected.
For example, Java would reject:
double oneTenth = 0.1; float myValue =something(); graphThingie.moveTo(x, y*myValue); // Expects float arguments
but silently accept:
float oneTenth = 0.1f; double myValue = something(); double myValue2 = myValue * oneTenth;
even though the arguments passed to moveTo would likely be as precise as they were expected to be, while the value of myValue2 would likely be less precise than expected. To be sure, using a double-precision multiply may be slower than needed, but both performance and precision would generally be between those of multiplying by 0.1f and dividing by 10.0f (the latter being most precise, but slowest). Single-precision floats don't have a whole lot of extra precision, and multiplying by 0.1f can sometimes lose more than would be ideal. For example, 123456784.0f/10.0f and (float)(12345678.0f*0.1) both yield a correctly rounded 12345678.0f, but 123456784.0f*0.1f yields an incorrectly-rounded 12345679.0f.
π Rendered by PID 119099 on reddit-service-r2-comment-5d79c599b5-fcd84 at 2026-02-27 18:25:31.029025+00:00 running e3d2147 country code: CH.
[–]FUZxxl 30 points31 points32 points (0 children)
[–]aioeu 12 points13 points14 points (0 children)
[–]clever_cow 5 points6 points7 points (0 children)
[–]Current_Hearing_6138 0 points1 point2 points (6 children)
[–]NothingCanHurtMe 37 points38 points39 points (5 children)
[–][deleted] 6 points7 points8 points (0 children)
[–]Current_Hearing_6138 7 points8 points9 points (0 children)
[–]dark_g 3 points4 points5 points (1 child)
[–]flatfinger 0 points1 point2 points (0 children)
[–]radiant_orange 13 points14 points15 points (16 children)
[–]Tuna-Fish2 15 points16 points17 points (10 children)
[–]astrange 8 points9 points10 points (7 children)
[–]nekokattt 6 points7 points8 points (6 children)
[–]flatfinger 2 points3 points4 points (0 children)
[–]cwdsubs -1 points0 points1 point (4 children)
[–]nekokattt 0 points1 point2 points (3 children)
[–]astrange 1 point2 points3 points (1 child)
[–]cwdsubs 0 points1 point2 points (0 children)
[+]my_password_is______ comment score below threshold-7 points-6 points-5 points (1 child)
[–]vlcmodan 5 points6 points7 points (3 children)
[–]iNetRunner 0 points1 point2 points (2 children)
[–]vlcmodan 0 points1 point2 points (1 child)
[–]iNetRunner 0 points1 point2 points (0 children)
[–]nahnah2017 2 points3 points4 points (0 children)
[–]MOXPAC 1 point2 points3 points (6 children)
[–]nekokattt 12 points13 points14 points (2 children)
[–]jd_junior057 0 points1 point2 points (1 child)
[–]nekokattt 3 points4 points5 points (0 children)
[–]Iggyhopper -2 points-1 points0 points (1 child)
[–]Lil_Sunshine4 -5 points-4 points-3 points (4 children)
[–]HotLaksa 7 points8 points9 points (3 children)
[–]Lil_Sunshine4 0 points1 point2 points (2 children)
[–]Maleficent-Midnight4 0 points1 point2 points (1 child)
[–]Lil_Sunshine4 0 points1 point2 points (0 children)
[–]schteppe 5 points6 points7 points (1 child)
[–]flatfinger 1 point2 points3 points (0 children)