int32_t到int64_t(或浮点)

时间:2014-02-26 14:44:37

标签: c casting

我有一个用C编写的非常简单的算法,它从int16_t数组中获取值,将这些值乘以它们的位置并存储到int32_t的数组中。还有另一个类型sum的变量int64_t,它存储了生成的_slops数组中所有值的总和。这是代码。

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

// these variables initialized separately

int16_t *from;
int32_t *_slops;
int32_t _overlapSize;
...

// main algorithm

int32_t pos;
int64_t sum = 0;
for(pos = 0; pos < _overlapSize; pos++) {
    _slops[pos] = (from[pos] * pos * (_overlapSize - pos));
    sum += (int64_t) _slops[pos];
    if (pos == 2) {
        LOGD("1 ---: %d", (from[pos] * pos * (_overlapSize - pos)));
        LOGD("2 ---: %d", _slops[pos]);
        LOGD("3 sum: %d", sum);
    }
}
LOGD("sum: %d", sum);

当我运行代码时,我发现_slops生成的数组中包含正确的值,但sum变量始终具有相同的值。

02-26 15:58:10.762: D/player(17466): 1 ---: 1154560
02-26 15:58:10.762: D/player(17466): 2 ---: 1154560
02-26 15:58:10.762: D/player(17466): 3 sum: 1504780888
02-26 15:58:10.762: D/player(17466): sum: 1504780904

02-26 15:58:10.840: D/player(17466): 1 ---: 890560
02-26 15:58:10.840: D/player(17466): 2 ---: 890560
02-26 15:58:10.848: D/player(17466): 3 sum: 1504780888
02-26 15:58:10.848: D/player(17466): sum: 1504780904

02-26 15:58:10.848: D/player(17466): 1 ---: 1791680
02-26 15:58:10.848: D/player(17466): 2 ---: 1791680
02-26 15:58:10.848: D/player(17466): 3 sum: 1504780888
02-26 15:58:10.848: D/player(17466): sum: 1504780904

我尝试将sum的类型更改为float,但结果保持不变。我很确定我在输入类型时遇到了问题(int32_tint64_tint32_tfloat),但我无法找到正确的方法它

在C中执行此操作的正确方法是什么?一般来说,如果我乘以两个int16_t值,以及得到更大结果的内容(假设int32_t),我该怎么做?任何帮助都非常感谢。

2 个答案:

答案 0 :(得分:4)

除非int64_t是您计算机上int的别名,否则您使用的是错误的printf格式指令。试试这个:

LOGD("sum: %" PRId64, sum);

PRId64<inttypes.h>中定义的宏。

如果您正在使用GCC,则使用-Wformat进行编译会产生有关格式不匹配的错误。 -Wall将包含-Wformat以及许多其他有用的警告。

关于你的第二个问题(关于如何扩展使用窄类型参数的二进制算术运算的结果),这可以通过使至少一个操作数达到你想要的宽度来完成。这可以通过演员表来完成:

int16_t a = A_VAL;
int16_t b = B_VAL;
int32_t c = a + (int32_t)b;

maverikanswer所示,您可能会在分配给_slops[pos]的表达式中出现有符号整数溢出。如果_overlapSize大于2 9 ,那么pos * (_overlapSize - pos)的最大乘积大于2 16 ,这意味着它的乘积对{{1}可能有大于2 31 的结果。

答案 1 :(得分:3)

问题在于:

_slops[pos] = (from[pos] * pos * (_overlapSize - pos));

_slops[pos]是一种int32_t。在某些情况下,(from[pos] * pos * (_overlapSize - pos))表达式无法存储在int32_t中,因为from[pos] int16_t乘以pos int32_t,结果可以大于int32_t(考虑int16_t的最大值为2^15int32_t的最大值为2^312^15 * {{ 1}} = 2^31,如果不截断,则无法存储为2^46

但是你把它写回int32_t _slops[pos]。在这一行:

int32_t
演员没用,也不能阻止缩小。我建议将sum += (int64_t) _slops[pos]; 类型更改为_slops或使用临时变量来计算结果:

int64_t *

我不知道int64_t tmp = ((int64_t) from[pos] * pos * (_overlapSize - pos)); 有多大,但从这个意义上说整体表达并不安全。