最佳答案
float ,按照IEEE 754 standard ,旨在快速且节省空间,但不精确。当您存储 float (REAL) 时,存储时会出现一些尾部错误。将有缺陷的(设计上)数据类型转换为精确的字符串表示形式并非易事,并且不同的实现会做出不同的假设。
下面是一个来自 C++ 的示例代码来说明这一点:
// the 'f' at the end of the literal signifies that the number is a 32 bit float
cout << "REAL" << endl;
cout << setprecision(10) << 0.1f << endl << 0.2f << endl << 0.3f << endl << 0.1f + 0.2f << endl;
cout << 0.525f << endl << 0.535f << endl;
/*
Output:
REAL
0.1000000015
0.200000003
0.3000000119
0.3000000119
0.5249999762
0.5350000262
*/
解决您的问题的一个方法是从一开始就使用更精确的数据类型 (LREAL)。再次使用 C++ 示例:
cout << "LREAL" << endl;
cout << setprecision(10) << 0.1 << endl << 0.2 << endl << 0.3 << endl << 0.1 + 0.2 << endl;
cout << 0.525 << endl << 0.535 << endl;
/*
Output:
LREAL
0.1
0.2
0.3
0.3
0.525
0.535
*/
不过,请记住,从 32 位 float 转换为 64 位会保留错误:
cout << "REAL to LREAL" << endl;
cout << setprecision(10) << (double)0.1f << endl << (double)0.2f << endl << (double)0.3f << endl << (double)(0.1f + 0.2f) << endl;
cout << (double)0.525f << endl << (double)0.535f << endl;
/*
Output:
REAL to LREAL
0.1000000015
0.200000003
0.3000000119
0.3000000119
0.5249999762
0.5350000262
*/
因此,如果您要使用不同的数据类型,请务必在需要精度的任何地方使用它。
除了使用 LREAL 之外,您还可以创建自己的十进制数字格式,例如存储两个整数,一个用于浮点之前的值,一个用于浮点之后的值,然后创建一个自定义字符串函数。但 99% 的情况下这都太过分了。
如果您知道您的数字只需要一定的精度,那么最简单的解决方案可能是仅限制浮点后的位数。就您而言,您可以直接截掉小数点后第三位之后的任何内容并完成它。
关于string - Codesys REAL_TO_STRING 中的意外功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76815060/