[英]int32_t to int64_t (or to float)
我有一個非常簡單的用C語言編寫的算法,該算法從int16_t
數組中獲取值,然后將這些值與其位置相乘,然后存儲到int32_t
數組中。 還有另一個類型為int64_t
變量sum
,用於將所有值的和存儲在結果_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_t
為int64_t
或將int32_t
為float
),但是我找不到正確的方法。
在C中執行此操作的正確方法是什么? 通常,如果我將兩個int16_t
值相乘,然后得到更大的結果(例如int32_t
),該怎么做? 非常感謝您的幫助。
除非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;
正如maverik的回答所表明的那樣 ,在分配給_slops[pos]
的表達式中,有可能出現有符號整數溢出。 如果_overlapSize
大於2 9 ,則pos * (_overlapSize - pos)
的最大乘積大於2 16 ,這意味着它與from[pos]
乘積可能大於2 31 。
這是問題所在:
_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^15
和最大值int32_t
即2^31
。 2^15
* 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));
我不知道有多大可以pos
是但整體表現是不是安全在這個意義上。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.