我有一个很长的双正弦和一个长的长放大器。我使用的是<cmath>
,代码如下:
sine = sin(point);
amp = round(sine * 2^31);
此处变量点以0.009375间隔递增。这里的第一行工作正常,但在第二行我收到此错误消息:
error: invalid operands of types 'long double' and 'int' to binary 'operator^'
我不确定这个错误意味着什么,这里的主要要求是&#39;我如何绕过这个以获得输出整数到变量放大器?&#39;
答案 0 :(得分:2)
在C ++中,^
运算符表示独占或不是取幂。你可能意味着(1ULL << 31
)。
答案 1 :(得分:0)
错误的原因是*
是乘法,^
是按位xor
运算符,只能应用于整数类型。
乘法(*
)的优先级高于^
。因此,编译器将amp = round(sine * 2^31);
解释为amp = round( (sine *2)^31);
。 sine
(可能)的类型为long double
,因此sine*2
的结果也属于long double
类型。 long double
不是整数类型,因此不能是^
的操作数。因此错误。
你的错误是假设^
表示取幂,而不是。{/ p>
您可以通过
解决问题amp = round (sine * pow(2.0, 31)); // all floating point
或
amp = round (sine * (1UL << 31));
第二个计算1
leftshifted 31位作为unsigned long
(保证能够代表结果,不像unsigned
或int
那样没有这样的保证)。然后,在进行乘法时,它会将该值提升为long double
。
如果您主要进行浮点运算,那么第一个对于维护此类代码的人来说更容易理解。第二个对于编写数字代码的人来说可能相当神秘,但是对于小小的操作并不熟悉 - 具有讽刺意味的是,你已经证明你^
是指数化的。
您需要进行测试以确定哪个选项可以提供更高的性能(因为需要在第二个中将unsigned long
转换为long double
,并且在第一个中优先考虑std::pow()
对于一些特殊情况)。换句话说,编译器优化器有可能在两种情况下都具有攻击性,或者pow()
的实现可以手工精心制作,或者两者兼而有之。