2014-04-04 214 views
2

我正在通過儀表的rs-232串行線讀取字符。由於校驗和字節是正確的,我百分之百肯定這些值都是正確的。令我困惑的是,代表壓力值的4個字節返回-0.000000。這個負面信號似乎並不正確。這裏是一個提取的例子:float在c中打印出負數0

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

unsigned char cmd[] = { 
    0x80, 0x00, 0x00, 0x00 
}; 

float float_byte_join(unsigned char *from, int size) 
{ 
    float value; 
    value = 0; 
    unsigned char * p = (unsigned char *)&value; 
    int i, j; 

    for (i = 0, j = size - 1; i < size; i++, j--) { 
     p[j] = *from; 
     ++from; 
    } 
     printf("value is %f\n", value); 
    return value; 
} 

int main(void) 
{ 
    float_byte_join(cmd, 4); 
    return 0; 
} 

// result: 
value is -0.000000 

任何想法爲什麼這打印-0.000000而不是0.000000?這4個字符真的代表負數嗎?我想補就沒有這樣的事,作爲一個負0

+1

是的。這是32位二進制浮點數的負數零表示形式。二的補碼沒有負的零,但是你沒有處理二進制補碼。 – hobbs

+2

注意:傳感器的-0.0可能有特殊含義或含義。說千分之0.001的壓力_reports_,但_measures_以更高的精度。像+0.0002和-0.0002這樣的值,如果沒有負值,則會變爲0.000。知道壓力是+還是 - 可能很重要。讀數-0.000可能表明_slow_泄漏。使用'int signbit(real-floating)'宏判斷其參數值的符號是否爲負數,因爲數學上-0.0和+0.0使用==,>等比較相同。 – chux

回答

4

兩個補整數沒有負零,但IEEE浮點值有一個負零,並且它的編碼形式80 00 00 00(十六進制,大端,單-精確)。所以如果這真的是你從設備獲得的字節序列,那麼這是正確的結果。

這篇文章以及其他很多有關IEEE浮點運算的奇怪之處在文章What Every Computer Scientist Should Know About Floating Point中有解釋和證明,因爲您是計算機科學家,您應該閱讀。

+0

http://docs.oracle.com/ cd/E19957-01/806-3568/ncg_goldberg.html –

+0

@LưuVĩnhPhúc謝謝,但這似乎是一個URL,可能不會在無限的未來保持良好。 (和我的一樣,唉,但我反正給它更好的機率。) – zwol

+1

如果你想消除-0的可能性,只需加0.0。 –

0

你的符號位(最顯著位)設置爲1,指定一個負數,將其更改爲0。

unsigned char cmd[] = { 
0x00, 0x00, 0x00, 0x00 
}; 

(但不管怎麼說:等於-0.0f == 0.0F)