2015-10-22 23 views
3

我在Arm設備上使用rapidjson並在運行此代碼時出現奇怪的行爲。如何隔離手臂設備上的故障?

#include <document.h> 
    using namespace std; 

int main() 
{ 
    const char json []="[{\"Type\":\"float\",\"val_param\" : 12.025 }]"; 

    rapidjson::Document d; 

    if(d.Parse<0>(json).HasParseError()) { 
    //ErrorCase 
    }else{ 
     rapidjson:: Value& val_param = d[0]["val_param"]; 
     double tmp_double1 = val_param.GetDouble(); 
     cout << tmp_double1 <<endl; // -9.2559641157289301e+61 instead of 12.025 
    } 

    return 0; 
} 

在投下這個問題之前。你還需要什麼信息?我真的不知道如何隔離這個故障。如果是因爲嵌入式設備或rapidjson而發生。以及如何解決它。

更新=================== =====================

什麼是設備? http://www.keith-koep.com/de/produkte/produkte-trizeps/trizeps-iv-m-eigenschaften/

它有硬件FPU嗎?這是ARMv5,所以我不這麼認爲。

你正在使用什麼編譯器和庫(版本號/特定版本)? 你傳遞給編譯器和鏈接器的選項是什麼?

arm-linux-gnueabi-g++ -march=armv5te -marm -mthumb-interwork --sysroot=/usr/local/oecore-x86_64/sysroots/armv5te-linux-gnueabi 
+0

什麼是'd_DOM'? – NathanOliver

+0

它應該是'd'。 –

+0

DOOM ..................... –

回答

2

看起來這可能是RapidJSON中的一個未定義行爲類型的錯誤。

由於您的目標是ARMv5,因此您可能使用的是使用傳統ARM FPA格式的軟件浮點庫(與之後的使用IEEE754格式的VFP相反)。至關重要的是,FPA以一種奇怪的中端格式存儲事物,其中64位雙打存儲爲兩個小端字,但最重要的字首先存儲。

(是的,大端ARM是一個整體的其他複雜的問題,但我刻意忽略它在這裏,因爲我沒有看到armeb-*三重或任何地方-mbig-endian選項)

考慮12.025爲IEEE754雙:

64-bit value:    0x40280ccccccccccd. 
little-endian byte order: cd cc cc cc cc 0c 28 40 
as little-endian words: 0xcccccccd 0x40280ccc 

現在FPA格式,這將是:

as little-endian words: 0x40280ccc 0xcccccccd 
byte order:    cc 0c 28 40 cd cc cc cc 

試圖在詮釋爲純粹的小端64位值會產生0xcccccccd40280ccc,這正好是-9.255965e + 61的IEEE754表示。看中了!


來自各地的代碼快看,它可能嚴格不止一個錯誤的不兼容,因爲RapidJSON似乎並明確承擔IEEE754格式的浮點值。值得稱道的是,儘管the parsing code看起來很毛茸茸,但我確實看到了unions而不是類型雙擊指針。但是,即使它不依賴於未定義的行爲,它仍然依賴於實現定義的行爲(浮點類型的格式),並且不幸的是,此編譯器的實現不符合該期望。

+0

非常感謝您的全面回答。所以我寧願使用其他的json解析器。或者仍然有機會實現它的工作? –