簡體   English   中英

int32_t到int64_t(或浮動)

[英]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_tint64_t或將int32_tfloat ),但是我找不到正確的方法。

在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乘以posint32_t ,結果可能大於int32_t (考慮最大值)對於int16_t2^15和最大值int32_t2^312^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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM