Question:
How do I typecast this in C++?
1970-01-01 00:00:00 UTC
How do I typecast this in C++?
Five answers:
husoski
2010-09-21 01:59:44 UTC
When you do a narrowing conversion, you need to provide a typecast to avoid a warning. A conversion is "narrowing" if the converting-from type has values that can't be exactly represented in the converting-to type. One example is the conversion from double to float on line 20 or the conversion from float to int on line 21. Make these:



fx = (float)dx;

ix = (int)fx;



...instead.



In the C++ version of (aka ) there are THREE overloaded definition of sqrt(), for float, double and long double types. Your call with an int argument isn't any of these, but the int actual argument could be promoted to any of those types. That's the ambiguity that your compiler is complaining about. Change line 26 to any (or even all) of:



cout << sqrt( (float)ix ) << endl;

cout << sqrt( (double)ix ) << endl;

cout << sqrt( (long double)ix ) << endl;



...to choose which data type to use for the calculation.



Edit: Oh yes, you have to do the same this with ix in the call to pow() in line 25. Cast it to float/double/long double.



Cubbi points out that static_cast(expr) is available in C++ as an alternative to the regular C-style (NewType)(expr) casts. That's good to remember for objects, particularly object pointers and references, but there's no difference when converting between the arithmetic types.



When you get into full-tilt object programming, the additional type-cast options in C++ allow different degrees of type-safe conversion of pointers and references to objects. Just for grins, I added a link to a nice rundown on these at stackoverflow.com.
j0wner
2010-09-21 01:27:44 UTC
What do you mean it "won't run"? It compiles and runs perfectly except for your call to "pause" which I don't have on my system and which you shouldn't even have in your program.
?
2010-09-21 01:40:30 UTC
The only diagnostics that I managed to squeeze out of my compiler were:



test.cc:20:14: warning: conversion to 'float' from 'double' may alter its value [-Wconversion]

test.cc:21:14: warning: conversion to 'int' from 'float' may alter its value [-Wconversion]

test.cc:28:17: error: 'system' was not declared in this scope



The first two can be silenced with explicit static casts, which will tell the compiler that you know what you're doing:

    fx = static_cast(dx);

    ix = static_cast(fx);



the last one is because you forgot to #include or , for system()



Incidentally, it is bad style to declare variables only to assign to them later. I would write

    double dx = 9.23e8;

    float fx = static_cast(dx);

    int ix = static_cast(fx);



Also, it is bad style to abuse std::endl. It is not a "portable end of line", contrary to what some old mistaken textbooks teach, it is shorthand to "<< '\n' << std::flush", where each call to std::flush incurs a delay on your program. It may not matter in this brief example, but it might matter in a long IO-bound program. If you pause your program with system("pause");, you will need only *one* flush (or endl), just before the system() call. If you pause your program with the much more portable cin.get(); or any other read from std::cin, the flush will be executed automatically for you, and you don't need any endl's at all.



PS: @Ratchetr: good catch. Looks like my gcc decides to perform integer-to-floating point conversion from int to double, perhaps out of compatibility with C, even though in C++ provides three equally valid overloads for sqrt (float, double, and long double). So yes, have to static_cast or C-cast there too. Microsoft has been very good with C++ standards compliance lately, under Herb Sutter. It's just that they still encourage a lot of extensions, silently.
Chavon C
2010-09-21 01:35:54 UTC
Are you receiving "errors" or "warnings." You should only be receiving "warnings" because of your assignments of more precise numbers to least precise types.



Ex: double X = 1.33333333;

int Y = X; //this will cause a warning, because "int" can only store whole numbers, and you will lose the ".333333333" in the assignment
Ratchetr
2010-09-20 18:48:31 UTC
Microsoft C++ fails to compile this:

error C2668: 'sqrt' : ambiguous call to overloaded function

...math.h(589): could be 'long double sqrt(long double)'

...math.h(541): or 'float sqrt(float)'

...math.h(127): or 'double sqrt(double)'



So, yes, they want a typecast on the ix parameter so they know if you want the float, double, or long double version of the function.

I would go with double myself:

cout << sqrt ((double)ix) << endl;

cout << pow (sqrt((double)ix), 2) << endl;



It's a bit questionable in my mind if they should fail this, but I'm not a C++ language cop, so can't say. Microsoft isn't always 100% standards compliant (except when they write the standard ;-)...but there is an ambiguity here. Not sure if the spec is 100% clear on how it should be resolved. (And way too lazy to search for it).



ETA: Just saw your last comment about implicit typecasts only. I can only think of 1 way to do that here:

cout << sqrt (ix + 0.0) << endl;

cout << pow (sqrt(ix + 0.0), 2) << endl;

Very ugly, but standard practice in Javascript. Not how I would do it in c*


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...