Float转string精度损失问题
std::vector
如果我们在使用json库序列化float数组时,要注意转换成string后,默认精度只有小数点后6位。如果要网络传输,可以使用base64编码,然后收到后再解码,这样就不会因为转换std::string导致精度损失。
使用std::cout 打印是也是,需要设置std::cout << std::fixed << std::setprecision(8)。
float
类型有其固有的限制,因为它是一种32位浮点数,它只能提供大约6到7位的十进制精度。如果你需要更高的精度,请考虑使用double
类型,它是一种64位浮点数,能够提供大约15到17位的十进制精度。
32位浮点数,它只能提供大约6到7位的十进制精度是由IEEE存储标准决定的。32位浮点数,通常指的是符合IEEE 754标准的单精度浮点数格式(float)。在这种格式中,一个浮点数由三个部分组成:
-
符号位(Sign bit):1位,用于表示正数或负数。
-
指数部分(Exponent):8位,用于表示数值的范围(大小)。
-
尾数或小数部分(Mantissa/Fraction):23位,用于表示数值的精度(有效数字)。
此外,即使你设置了更高的精度,也不能保证超出float
或double
本身能表达的精度范围的位数是准确的。这是浮点数表示法的固有限制,而不是格式化输出的问题。
std::to_string
对于浮点数转换使用默认的格式和精度,这通常是6位有效数字。
示例:
#include<string>
#include<iostream>
int main(){
float value = 3.14159265f;
std::string strValue = std::to_string(value);
std::cout << "The float value is: " << strValue << std::endl;
return0;
}
在上面的例子中,std::to_string
可能会产生一个字符串,如"3.14159"
,因为默认情况下它只保留6位有效数字,这可能导致精度损失。
#include<iomanip>
#include<sstream>
#include<string>
#include<iostream>
std::string floatToStringWithPrecision(float value, int precision){
std::ostringstream oss;
oss << std::fixed << std::setprecision(precision);
oss << value;
return oss.str();
}
int main(){
float value = 3.14159265f;
std::string strValue = floatToStringWithPrecision(value, 8);
std::cout << "The float value with more precision is: " << strValue << std::endl;
return0;
}
在这个修改后的例子中,你可以指定所需的精度,使float
转换为string
时不会丢失重要的精度。请记住,即使你指定了更高的精度,也不能保证超出float
原本精度的位数是准确的。