我有一个C/C++应用程序,它以字符串的形式将数值写入redis。我还有一个Java应用程序,它将从redis中读取这些值。有时,出于有效的原因,我们会得到一个浮点值,其值为NaN或-NaN。但是,在使用sprintf(charPtr, "%e", dblVal);时,该值将以nan的形式输出。我还在%E中尝试了同样的语句,结果产生了NAN。当Java试图通过Float.parseFloat()或Double.parseDouble进行解析时,它会抛出一个NumberFormatException。
这个应用程序已经从Solaris移植到Linux,随后进行了一些Linux升级,并且在某个时候"nan“变成了"NaN”。我无法确定到底是什么升级引入了这种行为。
我已经完成了一段使用cmath std::isfinite()和std::isnan()的摘录,并最终可以定义自己的有效(-)NaN或(-)Infinity字符串,但这似乎不需要重新创建规范化的NaN和无限字符串。在C端输出inf时,无穷大可能有点不同,但Java想要Infinity。
最终,我需要能够解码C++应用程序用Java编写的数据。nan和inf不能被编写的Java解码。我关注的是NaN,但是无限是一个应该涵盖的案例。
发布于 2019-02-20 23:58:31
为什么不直接在java代码中使用这样的东西来解析一个双变量呢?
double parseDouble(String s) throws NumberFormatException {
try {
return Double.valueOf(s);
} catch (NumberFormatException e) {
if (s.equalsIgnoreCase("nan")) {
return Double.NaN;
} else if (s.equalsIgnoreCase("inf") || s.equalsIgnoreCase("+inf")) {
return Double.POSITIVE_INFINITY;
} else if (s.equalsIgnoreCase("-inf")) {
return Double.NEGATIVE_INFINITY;
} else {
throw e; // Invalid string
}
}
}发布于 2019-02-21 09:06:39
根据ISO/IEC 9899:2001,Linux的情况是(a)正确的行为
%e,%E表示无穷大或NaN的double参数以f或F转换说明符的样式进行转换。
的文本
表示无穷大的双参数在
[-]inf或[-]infinity(即实现样式)定义的样式中进行转换。表示NaN的双参数在样式[-]nan或[-]nan(n-char-sequence)中转换--这种样式和任何n-char序列的含义都是实现定义的。F转换说明符分别生成INF、INFINITY或NAN,而不是inf、infinity或nan。
也就是说,在Java中最安全的方法是尝试解析双字符,如果这一分析失败,则用小写的String并测试-作为第一个字符的存在,以及在使用.startsWith("nan")和.startsWith("inf")进行可能的符号之后的剩余部分。
当然,如果您需要支持不符合标准的Windows运行时,这也于事无补。
发布于 2019-02-22 04:37:04
一种可能更普遍的选择是将浮点数写入redis时转换为十六进制,然后在读取时再转换回来。这将确保通过将其转换为十进制字符串不会造成任何精度损失,但也会涵盖+/-Inf和NaN的情况。
这是可能的,因为双方都使用IEEE浮点数.
https://stackoverflow.com/questions/54797006
复制相似问题