2012-07-24 168 views
2

我需要將IEEE單精度浮點數編寫到特定地址的32位硬件寄存器中。爲此,我需要將float類型的變量轉換爲無符號整數。我能得到整數表示這樣的:獲取浮點型IEEE單精度位

float a = 2.39; 
unsigned int *target; 
printf("a = %f\n",a); 
target = &a; 
printf("target = %08X\n",*target); 

返回:

a = 2.390000 
target = 4018F5C3 

都很好。然而,這會導致編譯器警告「cast.c:12:警告:從不兼容的指針類型分配」

是否有任何其他方法可以執行此操作,但不會生成警告?這是針對特定的硬件,我不需要處理不同的排序等,我不想循環通過每個字符出於性能的原因,因爲一些其他問題往往表明。好像你也許可以在C使用的reinterpret_cast ++但我用C.

回答

5

您可以使用雙關類型與工會,

union { 
    float f; 
    uint32_t u; 
} un; 
un.f = your_float; 
uint32_t target = un.u; 

得到位。或者您可以使用memcpy

+0

+1,用於memcpy。 – user7116 2012-07-24 19:49:48

1

你可以創造一個包含float和一個unsigned int一個union類型,值存儲到上浮部件,然後將其讀出的整型,像這樣:

union reg_val 
{ 
    float f_val; 
    unsigned int i_val; 
} myRegister; 
myRegister.f_val = 2.39; 
printf("target = %08X", myRegister.i_val); 
0

如果你想簡單地顯示float積分值因爲它存儲在內存中,然後嘗試使用一個聯盟:

union { 
    float a; 
    unsigned int target; 
} u; 

商店的浮點值:

u.a = 2.39; 

打印兩個浮點和整數:

printf ("a = %f\n", u.a); 
printf ("target = %08X\n", u.target); /* you could use %u to show decimal */ 

沒有編譯器警告。我在Linux上使用GNU編譯器(gcc)。 請注意,target而不是指針;這是工會的美麗(和醜陋)。 ;-)

+0

達恩...丹尼爾F.和頭髮葡萄乾打敗了我。猜猜我應該輸入更快! – pr1268 2012-07-24 20:03:42

0

編輯:工會解決方案在任何地方工作我曾嘗試過但在某些地方因此我被指出標準,顯示它沒有工作。在評論中看到下面的鏈接,在這裏找到更多的信息(謝謝丹尼爾!)。假設工作或不應該工作,我會小心使用它,我想endianness等也參與(雙打破字節等)。

另一種解決方案是虛擬asm函數。例如在臂:

.globl echo 
echo: 
    bx lr 


unsigned int echo (float); 
... 
unsigned int ra; float f; 
f=1.0; 
ra=echo(f); 

需要一些拆卸,需要是不必須隨身攜帶的漂浮的FPU和/或採用GPRS的系統上。

memcpy如前所述是最乾淨和最可靠和便攜的解決方案(注意字節順序)。

+1

除非自上次草稿以來發生了更改,否則6.5.2.3中的腳註95說:「如果用於讀取聯合對象內容的成員與上次用於在對象中存儲值的成員不相同,則適當的部分的值的對象表示被重新解釋爲6.2.6中描述的新類型的對象表示(有時稱爲「類型雙引號」),這可能是陷阱表示。「,所以它正式應該工作。 (好吧,腳註只是信息性的,所以它沒有明確要求工作)。 – 2012-07-24 20:47:43

+1

@DanielFischer:n1124草案似乎沒有這個腳註(或者我錯過了它)。 6.2.6.1.7節似乎收縮了這種情況:「當值存儲在union類型的對象的成員中時,對象表示的不對應於該成員但與其他成員相對應的字節取未指定的值。 「附錄J.1重申了這一警告,聲稱以下內容沒有說明:「存儲在(6.2.6.1)」 – sfstewman 2012-07-24 20:54:30

+1

中的最後一個工會成員的價值啊,我談到了n1570(C11)。對不起,沒有提到。 – 2012-07-24 20:57:12