2017-05-01 73 views
-1

使用小數部分我有一個計算其爲以下:在固定點計算

1472/48 = 30.666667 
(30 * 48) = 1440 
(0.666667 * 48) = 32 

所以數字我NEAD是1440和32,其可與實數部分和的小數部分來計算第一次計算。 使用下面的一段代碼我找到了真正的部分,但小數部分是在一個規模。

#define SHIFT_AMOUNT 16 
// 2 bytes is used to map divisions 
#define SCALE_FACTOR 65535 // (2^16) 
#define SHIFT_MASK  ((1 << SHIFT_AMOUNT) - 1) 

uint32_t total_msgs = DATA_LENGTH << SHIFT_AMOUNT; 
total_msgs /= PAYLOAD_SIZE; 

uint8_t real_part = total_msgs >> SHIFT_AMOUNT; // 30 
uint32_t decimal_part = total_msgs & SHIFT_MASK; // 43690 

現在爲最後一次計算我卡住了。我如何得到43690 32(這確實是((六萬五千五百三十五分之四萬三千六百九十)= 0.666667)

+0

這不會導致您的問題,但2^16 = 65536,而不是65535 – harold

+0

整數的實數部分是一個實數部分。術語「實部」只對複數有意義。整數除法沒有小數部分。 – Olaf

+1

另外你也許應該澄清你真正想要計算的東西,現在有不同的答案,假設不同的事情。 – harold

回答

2

通常的辦法來解決這個問題是%操作:

quotient = DATA_LENGTH/PAYLOAD_SIZE; 
fraction = DATA_LENGTH % PAYLOAD_SIZE; 
+0

在一些糟糕的優化編譯器上,這可能會導致真正的分裂。 – Olaf

+0

我不認爲這是可能的..謝謝,修正它! – boortmans

+0

@olaf:那是真的。另一方面,如果'PAYLOAD_SIZE'是一個常量,一個好的編譯器可能不使用分區;如果它很重要,可以手動插入相應的代碼。 – rici

1

正如其他人所提到的,由於你所需要的數值商和從餘數的整數部分,你可以使用/%運營商分別做:

int quot = 1472/48; 
int rem = 1472 % 48; 

然而,而這樣做兩個獨立的操作具有相同對數字的,你可以使用div功能:如果你經常在執行這個特殊的計算

div_t result = div(1472, 48); 
printf("quotient=%d, remainder=%d\n", result.quot, result.rem); 

,這可能會給你的速度增加一些處理器(尤其是86)給你一個兩個值指令,所以它可能會將分割操作的數量減半。

+1

我希望編譯器合併這些操作無論如何(海灣合作委員會和克朗會),不能傷害,使其明確當然 – harold