conversion warning with STL combination of functors

G

Gilles Rochefort

Hello,

I wrote the following code to wrap some existing C functions, and I get
some warning about converting float to int.

float zfactor;
int tmp_x[4], corners_x[4];

std::transform(tmp_x,tmp_x+4,corners_x, bind2nd( multiplies<float>(),zfactor) );


I know that I can solve the problem by writing a dedicated functor, but
I'd like to know if it exists a proper solution to do it in just one line
as above. I have to precise that I don't want to use SGI extensions such
as compose1, I look for a standard STL form.

Any ideas will be appreciated !

Regards,
Gilles Rochefort
 
P

Pete Becker

Gilles said:
Hello,

I wrote the following code to wrap some existing C functions, and I get
some warning about converting float to int.

float zfactor;
int tmp_x[4], corners_x[4];

std::transform(tmp_x,tmp_x+4,corners_x, bind2nd( multiplies<float>(),zfactor) );


I know that I can solve the problem by writing a dedicated functor, but
I'd like to know if it exists a proper solution to do it in just one line
as above. I have to precise that I don't want to use SGI extensions such
as compose1, I look for a standard STL form.

The code coverts a float to an int, so the warning is, technically,
correct. Turn it off or ignore it if the code is, in fact, correct.
 
J

Jim Langston

Gilles Rochefort said:
Hello,

I wrote the following code to wrap some existing C functions, and I get
some warning about converting float to int.

float zfactor;
int tmp_x[4], corners_x[4];

std::transform(tmp_x,tmp_x+4,corners_x, bind2nd(
multiplies<float>(),zfactor) );


I know that I can solve the problem by writing a dedicated functor, but
I'd like to know if it exists a proper solution to do it in just one line
as above. I have to precise that I don't want to use SGI extensions such
as compose1, I look for a standard STL form.

Any ideas will be appreciated !

Regards,
Gilles Rochefort

Well, it looks like you are multiplying a float by an int. So the warning
is, in fact, correct because of the conversion involved.

Multiplying a float by an int can get complicated because you either need to
convert the float to an int first, or convert the int to a float. In most
cases you would want to convert the int to a float. The reason being:
float x = 0.25;
int y = 4;

Now, mulitplying x times y can produce either 0 or 1 depending on which
conversion is done.

I think you need to look at what you are doing and rethink the math.
 
P

Pete Becker

Jim said:
Multiplying a float by an int can get complicated because you either need to
convert the float to an int first, or convert the int to a float. In most
cases you would want to convert the int to a float. The reason being:
float x = 0.25;
int y = 4;

Now, mulitplying x times y can produce either 0 or 1 depending on which
conversion is done.

Given those definitions, the expression x*y has type double. Both
operands are converted to double and then multiplied.
 
E

Earl Purple

Pete said:
Given those definitions, the expression x*y has type double. Both
operands are converted to double and then multiplied.

Do they need to? float * int could return double but that doesn't mean
that the integer has to be converted first. In fact I would hope that
when multiplying by a constant 4, the compiler would be clever enough
to simply add 2 to the exponent. Even if it's a variable y I would hope
the compiler might be able to perform an optimal float*int (presumably
more efficient than float * float ).
 
E

E. Mark Ping

Given those definitions, the expression x*y has type double. Both
operands are converted to double and then multiplied.

Okay, I'm baffled. I would have expected a conversion to float.
Section 5/9 of the standard suggests the same as I understand it.
What am I missing?

quoting the standard:
Many binary operators that expect operands of arithmetic or enumeration
type cause conversions and yield result types in a similar way. The purpose
is to yield a common type, which is also the type of the result. This
pattern is called the usual arithmetic conversions, which are defined as
follows:
- If either operand is of type long double, the other shall be converted to
long double.
- Otherwise, if either operand is double, the other shall be converted to
double.
- Otherwise, if either operand is float, the other shall be converted to
float.
- Otherwise, the integral promotions (4.5) shall be performed on both
operands.54)
- Then, if either operand is unsigned long the other shall be converted to
unsigned long.
- Otherwise, if one operand is a long int and the other unsigned int, then if
a long int can represent all the values of an unsigned int, the unsigned int
shall be converted to a long int; otherwise both operands shall be converted
to unsigned long int.
- Otherwise, if either operand is long, the other shall be converted to long.
- Otherwise, if either operand is unsigned, the other shall be converted to
unsigned.
 
P

Pete Becker

E. Mark Ping said:
Given those definitions, the expression x*y has type double. Both
operands are converted to double and then multiplied.


Okay, I'm baffled. I would have expected a conversion to float.
Section 5/9 of the standard suggests the same as I understand it.
What am I missing?
[/QUOTE]

Nothing. The type of the x*y is, indeed, float.

For some reason I thought a floating-point was performed. But 5.6/2
(Multiplicative operators) says "... The usual arithmetic conversions
are performed on the operands and determine the type of the result."
You've given the details of the usual arithmetic conversions, and
there's no floating-point conversion there.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top