簡體   English   中英

更有效的處理我的數據的方法(整數和浮點數)

[英]More efficient way of dealing with my data (ints vs floats)

對於十六進制,我的大腦放屁很多。 有些人是靈巧的,而其他人只是簡單的右手...好吧,有點像那樣,我猜我是非常基礎的。

無論如何......我正試圖讓一些固件更有效率。 我們有一個功能,它根據通過CANBUS獲得的一些十六進制數據來計算車輛的速度。 現在我正在將它轉換為浮點數,所以我可以把它包裹起來但是我想知道如果我們把它放在整數格式中我們是否會使用更少的ROM空間? 這可以做到而不會失去准確性嗎? 現在我的花車精確到1/16千瓦時。 我知道這個功能看起來很簡單,但是每秒運行數百次就會讓它變得有點麻煩。

首先,這是一些示例數據:

[06] [3c] ...... [06] [3a] ... [06] [3b] ...... [06] [46] ... [06] [3b] ...

我已經將其他6個字節留下,因為它們與速度無關。 左邊的字節我們稱之為speed_a,右邊的字節是speed_b。 這是轉換的功能:

float calculateSpeed()
{
    float speed;
    speed = ( ( float )speed_a * 256.0 + speed_b ) / 16.0;
    return speed;
}

所以上面的數據會轉化為:

99.7500 99.6250 99.6875 100.3750 99.6875

這確實反映了以kph為單位的車輛的真實速度。 對於我們的應用,我們並不關心真正的速度是什么,因為一切都是相對的。 只要我們不失去決心,我們就會感到高興。 我想過只保留INT形式的所有內容,但是當你除以16時它只是截斷。

我對大多數事情都不是個白痴......但我對base2來說是個白痴。

Lil'幫忙嗎? 謝謝。

根本不要除以16.0。 您仍然可以比較,排序,添加或減去速度。

整數總是比浮點數快。 不使用浮點數來表示kph,而是使用整數來表示kph的1/16。

然后你的代碼變成:

int calculateSpeed() {
    return speed_a * 256 + speed_b
}

只有在您需要向用戶顯示值時,我才會轉換回浮點數:

int s = calculateSpeed();
printf ("Speed = %f\n", ((float)(s))/16.0);

取決於你的編譯器的智能程度,以及你的CPU有多好(我可能是錯的,但這聽起來像一個嵌入式系統),行:

    return (speed_a << 8) + speed_b

可能會更快。

您可以使用0.01的比例。 然后整數9969表示99.69kph。 這將避免基礎2的復雜化。

0.01比分辨率0.0666好六倍。 兩倍的好就足夠了。 然后,每次測量可以使用2個字節,最高可達327 kph。

如果需要除以100(例如輸出),則有近似的方法,但快速除以常數 (在大小寫中為100)。

如果根據您描述的要求使用定點數學運算,您將節省給定精度的空間,因為您可以僅使用您需要的位數來存儲小數部分。

但是,大多數編譯器將浮點數存儲為32位值,而我見過的大多數定點數學庫也使用32位作為存儲。 除非您可以使用16位定點數表示所需的數字范圍(整數和小數部分),否則float和(32位)int之間不存在存儲差異。

底線除非你想處理16位定點數,否則int和float可能會在你的系統上使用相同數量的存儲空間。

你可以選擇:

int calculateSpeed () {
    int speed;
    speed = ( (speed_a * 256 ) + speed_b );    
    return speed;
}

我只是基本上刪除了div部分,因為你不需要它:int至少是32位 - 而你有2個字節,一共是16位。

史蒂芬,

整數除法只給出整數結果。 實(浮點)除法給出浮點結果。

在您的情況下,您可以將其存儲為米,或厘米甚至每秒微米。 然后當你進行適當比例的整數除法時,你不會關心截斷,你可以將轉換推遲到Kph,直到打印/顯示結果(或導出到任何期望這些單位的東西等)。

順便說一下,另一種舊方法是執行(整數)除法和模數運算對......將結果存儲為商/余數對,直到打印/顯示/輸出為止。 已經有了這種“縮放整數算術”模型實現的整個數學例程庫......與浮點計算相比,它可以提供顯着的性能和精度優勢。

是否允許丟失數據? 如果不是,你不能對這個小數做多少......否則:

int speed = ((float_a << 8) | float_b) >> 4;

將兩個char設為short並刪除最后4位(與將其除以16得到整數部分相同)。

使用按位運算時,你也可以獲得性能提升,這比使用乘法/除法要快一些(盡管這種增益對於實際的計算機來說幾乎無關緊要)。

如果您只想轉換為十進制數字進行顯示 ,而不使用浮點運算,如果以十六分之一公里/小時的speed測量speed ,您可以執行以下操作:

printf("%d.%04d", speed / 16, 10000 * (speed % 16) / 16);

在嵌入式環境中,如果不需要在任何浮點算術庫中進行鏈接,則可以節省大量 ROM空間。 聽起來你可能不希望在應用程序中消除浮點的所有使用。 (更不用說還避免使用printf() ,但這是另一個故事。)

如果您的測量設備提供的精度不超過十六分之一,則顯示超過兩位小數位是沒有意義的。 考慮到該格式的上述示例的修改留給讀者練習。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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