Reputation:
I have a long double sine and a long long int amp. I am using <cmath>
and have code as follows:
sine = sin(point);
amp = round(sine * 2^31);
Here the variable point is incrementing in 0.009375 intervals. The first line here works fine but on the second I receive this error message:
error: invalid operands of types 'long double' and 'int' to binary 'operator^'
I'm unsure what this error means and the main request here is 'How can I get around this to get an output integer into the variable amp?'
Upvotes: 1
Views: 1032
Reputation: 36617
The reason for the error is that *
is multiplication, and ^
is the bitwise xor
operator which can only be applied to integral types.
Multiplication (*
) has higher precedence than ^
. So the compiler interprets amp = round(sine * 2^31);
as amp = round( (sine *2)^31);
. sine
(presumably) has type long double
, so the result of sine*2
is also of type long double
. long double
is not an integral type, so cannot be an operand of ^
. Hence the error.
Your mistake is assuming that ^
represents exponentiation, which it does not.
You can fix the problem by either
amp = round (sine * pow(2.0, 31)); // all floating point
or
amp = round (sine * (1UL << 31));
The second computes 1
leftshifted 31 bits as an unsigned long
(which is guaranteed able to represeny the result, unlike unsigned
or int
for which there is not such a guarantee). Then, in doing the multiplication, it promotes that value to long double
.
If you are doing predominantly floating point operations, the first is more understandable to people who will maintain such code. The second is probably rather cryptic to someone who writes numeric code but is not well acquainted with bit fiddling operations - as, ironically, you have demonstrated in your belief that ^
is exponentiation.
You would need to test to determine which option offers greater performance (given the need to convert unsigned long
to long double
in the second , and potential for std::pow()
in the first to be optimised for some special cases). In other words, there is potential for the compiler optimiser to get aggressive in both cases, or for the implementation of pow()
to be lovingly hand-crafted, or both.
Upvotes: 0
Reputation: 96301
In C++ the ^
operator means exclusive or, not exponentiation. You probably meant (1ULL << 31
).
Upvotes: 2