我必须将整数值乘以2 ^ 31。我用google搜索它,看起来双打的范围在2.23e-308< = | X |当使用64位时,< = 1.79e308,并且在1.18e-38< = | X |之间的浮点数< = 3.40e38。
这比我需要的要多得多。但它不起作用。
我的头文件中有这个常量值:
static const float SCALE_FACTOR = 2^-31;
然后我就这样做了:
float dummy = SCALE_FACTOR;
然后,哑的值是11.
我不知道问题是否正在分配这样的常量值,但我不知道如何写它而不会失去精度。
任何帮助?
编辑:对不起,愚蠢的问题。我的MatLab背景背叛了我,忘记了^不是用于C ++中的取幂。我投票结束了。答案 0 :(得分:3)
^是C ++中的按位xor运算符,而不是数学取幂运算符。你有几个选择。
float
中,你可以计算出基础10 e
格式文字并使用它:或许类似于{{1}为2 ^ -31。这很容易出错(例如我做了一个),并且不一定能在浮点格式之间移植。4.6566128730773926e-010
表示2 ^ 31或0x80000000
表示例如2 ^ -31。当然,您可以使用某种1UL << 31
函数来计算运行时的值。
顺便说一句,如果你使用整数,为什么不使用1.0f / 0x80000000
或其他64位整数类型,而不是浮点数,这可能会给你带来舍入错误?从您的问题来看,您是否正在查看浮点值是不完全清楚的,因为您需要浮点值范围,或者您只是担心溢出32位整数值。
答案 1 :(得分:1)
在您的代码中
static const float SCALE_FACTOR = 2^-31;
static
是多余的(默认情况下常量有内部链接),^
表示按位异或,-
没有意义(至少如果你想“乘以2 ^ 31“如上所述),float
是不必要的特殊选择,而不是默认的浮点类型double
(例如,3.14
等浮点文字的类型
此外,在C ++保留中呼叫宏的所有UPPERCASE标识符(常见约定)。将它们用于常量是一种Java主义。具有讽刺意味的是Java约定起源于C,其中过去的常量必须表示为宏。
相反,请写下
double const scale_factor = 1uL << 31;
,其中
未明确指定内部链接(关键字static
),
使用默认浮点类型double
代替float
,
不使用ALL UPPERCASE标识符(应为宏保留),
使用左移位<<
来计算2的幂,而不是错误的^
,
不添加任何无意义的减号,
使用unsigned long
类型(由uL
指定),以确保有足够的范围。
答案 2 :(得分:0)
^
是按位异或的运算符,不是用于提升功率。您需要std::pow()
。
答案 3 :(得分:0)
乘以2的幂相当于左移那个幂。要将整数乘以2乘以31,只需将其移位:
unsigned long value = whatever;
unsigned long value_times_2_to_the_31 = value << 31;
这里不需要浮点数学。但仅仅为了完整性,要产生2到31的双倍值:
double two_to_the_31 = std::ldexp(1.0, 31);
请注意,虽然带有signed类型的shift表达式的结果在某些情况下会被正式定义,但这会导致溢出整数类型;使用浮点数学而不是消除溢出,它只是将它放入代码的不同部分。