将2 ^ 31分配给float或double

时间:2012-11-14 12:35:24

标签: c++ floating-point double floating-point-precision double-precision

我必须将整数值乘以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 ++中的取幂。我投票结束了。

4 个答案:

答案 0 :(得分:3)

^是C ++中的按位xor运算符,而不是数学取幂运算符。你有几个选择。

  1. 因为你将常量存储在一个本质上有损的格式float中,你可以计算出基础10 e格式文字并使用它:或许类似于{{1}为2 ^ -31。这很容易出错(例如我做了一个),并且不一定能在浮点格式之间移植。
  2. 您可以使用可在编译时计算的常量表达式设置常量,并使用整数文字:{^ 1}}或4.6566128730773926e-010表示2 ^ 31或0x80000000表示例如2 ^ -31。
  3. 当然,您可以使用某种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表达式的结果在某些情况下会被正式定义,但这会导致溢出整数类型;使用浮点数学而不是消除溢出,它只是将它放入代码的不同部分。