在运行此代码时,我在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;
}在否决这个问题之前。你还需要什么信息?我真的不知道如何隔离这个错误。如果是因为嵌入式设备而发生,还是快速增长。以及如何解决这个问题。
==========================更新========================================
设备是什么?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发布于 2015-10-23 10:36:26
这看起来可能是RapidJSON中一个未定义的行为类型错误。
由于您的目标是ARMv5,您可能使用的是使用遗留ARM FPA格式的软件浮点库(而不是使用IEEE754格式的后来的VFP )。关键的是,FPA以一种奇怪的中端格式存储东西,其中64位双字节存储为两个小尾字,但最重要的字首先存储。
(是的,大端手臂是另一个复杂的问题,但我在这里故意忽略它,因为我在任何地方都没有看到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试图将其解释为纯小endian 64位值会产生0xcccccccd40280ccc,这恰好是-9.255965e+61的-9.255965e+61表示形式。太好了!
简单地看一下代码,它可能更多地是不兼容的,而不是bug,因为RapidJSON似乎确实显式地采用了浮点值的IEEE754格式。值得称赞的是,尽管解析代码看起来很多毛,但我确实看到了工会而不是类型双关语。然而,即使它不依赖于未定义的行为,它仍然依赖于实现定义的行为(浮点类型的格式),不幸的是,这个编译器的实现不符合这个期望。
https://stackoverflow.com/questions/33284664
复制相似问题