如何在 c++ 中解析和拆分双精度
How to parse and split a double in c++
我有三个数字:
double n1 = 1.1
double n2 = 1.10
double n3 = 1.101
我希望将它们转换为字符串以分隔小数部分以在其他地方使用它们。因此,我希望有以下内容:
string s1 = 1
string s2 = 10
string s3 = 101
我读到这不可能使用std::to_string
因为它总是返回所有小数,例如s3
会像101000
.
然后我尝试了以下方法:
double n3 = 1.101;
std::ostringstream strs;
strs << n3;
std::string str = strs.str();
boost::char_separator<char> sep(".");
boost::tokenizer<boost::char_separator<char>> tokens(str,sep);
for (const auto& t : tokens) {
EV << "separated parts " << t << endl;
}
这在n1
和n3
情况下都很好用,但是当我使用n2
时,它会返回1
而不是10
。
我正在考虑如何解决这个问题,唯一的事情是在转换为字符串之前计算精度,然后再次设置精度。
这是一个可行的策略吗? 我如何计算点后有多少位数字?
如果你的数字最初出现在数据类型double
中,那么我认为没有机会将用于初始化的文字中写的小数部分分开。这些信息只是丢失了,因为我将尝试在以下段落中解释:
请注意,文字1.10
和1.1
都代表类型double
的数字文字。编译器会将两个文字转换为浮点表示/二进制表示,1.10
和1.1
将实现完全相同的二进制表示。因此,您将没有任何机会找出双精度值是否已使用文字1.1
或1.10
初始化。
当我们考虑到十进制数1.1
没有精确的二进制表示但会导致重复分数时,情况变得更糟:
0.1₁₀ = 0.0001100110011001100110011001100110011001100110011…₂
因此,当您打印出文字1.1
(或1.10
,这是相同的)时,这取决于您要舍入的精度:
std::cout << "1.1 is..." << std::setprecision(6) << 1.1 << std::endl;
std::cout << "1.1 is..." << std::setprecision(17) << 1.1 << std::endl;
// 1.1 is...1.1
// 1.1 is...1.1000000000000001
这意味着 - 一旦存储为双精度值,根据用于打印值的精度,您将获得不同的结果;这也适用于将小数部分转换为字符串,这实际上与以特定精度打印相同。
更糟糕的是,由于无法以二进制形式准确表示每个十进制值,两个不同的十进制值可以以二进制形式产生相同的值:
double n1 = 1.1;
double n2 = 1.100000000000000088817841970012523233890533447265625;
if (n1 == n2)
std::cout << "equal!" << std::endl;
// Output: equal!
所以你再也分不清n1
和n2
了。
很多话,还有一个简短的结论:
如果要区分1.1
和1.10
,或者通常要找出源代码中编写的数字文本的小数部分,则必须首先将它们存储为字符串,而不是双精度
我猜你不熟悉"浮点"数字到底是什么。
双精度数是浮点数,如 https://en.wikipedia.org/wiki/IEEE_floating_point 中所述。基本上1.10
和1.1
一样,和1.1000000
一样,以此类推。
现在,有解决方案称为"定点数",通常称为"小数"和"数字"。如果您熟悉数据库引擎,您就会知道 1.10 是数字 (3,2),1.1 是数字 (2,1)。请注意类型如何更改并定义精度(位数)和小数位数(逗号后的位数)。但是,C++本身不支持小数。
这只是简单的数学。 解析器只是将您的 x.10 转换为 x.1 :)
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何使双精度值的 C++ 和 C# 中的结果相同
- 使用浮点数和双精度数的非常小数字的数学
- 使用 Xcode 将双精度存储在数组C++中
- 在 C++ 中将双精度变量写入二进制文件
- 如何从字符串转换为双精度*
- 为什么我的数组双精度函数不起作用?
- 高精度双精度的 Sprintf 格式化问题
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 将指针数组分配给双精度
- 如何在 c++ 中解析和拆分双精度
- 拆分64位值以适应双精度参数类型