您有2個問題。
charg < discharg
爲使創建的爲4294965817一charg - discharg
環繞的答案。請看下面爲什麼你最終以13294718結束。
在/1000
之前進行偏置(+0.5),否則整數除法將全部準備好拋出小數部分。
建議修復1:確保charg> = discharg。
OR
推薦修復1:變化臨時代辦,discharg,TIME_NOW,time_old也許棉絮到int32_t
。
推薦修復2:改變你的舍入到batt += (uint32_t) ((Product/1000.0) + 0.5);
OR
推薦修復2:改變你的舍入到batt += (Product + 500*sign(Product))/1000;
表觀不確定的代碼 - 分步實施。
uint32_t batt = 8999824;
uint32_t charg = 21;
uint32_t discharg = 1500;
uint32_t time_now = 181;
uint32_t time_old = 132;
// batt += (uint32_t) ((((charg - discharg) * (time_now - time_old))/1000) + 0.5);
// The big problem occurs right away.
// Since charg is less than discharg, and unsigned arithmetic "wrap around",
// you get (21 - 1500) + 2**32 = (21 - 1500) + 4294967296 = 4294965817
uint32_t d1 = charg - discharg;
uint32_t d2 = time_now - time_old; // 49
// The product of d1 and d2 will overflow and the result is mod 4294967296
// (49 * 4294965817) = 210453325033
// 210453325033 mod 4294967296 = 4294894825
uint32_t p1 = d1 * d2;
uint32_t q1 = p1/1000; // 4294894825/1000 = 4294894.825. round to 0 --> 4294894
double s1 = q1 + 0.5; // 4294894 + 0.5 --> 4294894.5;
uint32_t u1 = (uint32_t) s1; // 4294894.5 round to 0 --> 4294894
batt += u1; // 8999824 + 4294894 --> 13294718
'charg - discharg'使無符號整型溢出。 – MYMNeo 2013-04-22 08:09:57
'charg - discharg'對你的輸入不重要。 – 2013-04-22 08:10:09
'charg - discharg'低於零,因此溢出。那是故意的嗎? – CodesInChaos 2013-04-22 08:10:13