2017-04-14 16 views
0

分裂双重我有这三个数字:如何解析和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; 
} 

这个作品在n1n3情况很好,但是当我使用n2返回1,而不是10

我在想如何解决这个问题,唯一的问题是在转换为字符串然后再次设置精度之前计算精度。

这是一个可行的策略吗? 如何计算点后有多少位数?

+0

'1.1 == 1.10',没有区别。 – Jarod42

+0

简单的初等数学,它在小数部分末尾有多少零并不重要。因此,1.1 == 1.10,也1.10 == 1.100000000000000000 ... –

+0

为什么不使用['std :: modf()'](http://en.cppreference.com/w/cpp/numeric/math/modf) ? – piwi

回答

2

如果你的号码最初是在数据类型double出现,那么,我认为没有机会的小数部分写在用于初始化文字分开。这些信息简单地丢失,我会尝试在下面的段落解释:

注意文字1.101.1都站了数字文本double类型。编译器会将文字转换为浮点表示/二进制表示,并且1.101.1将实现完全相同的二进制表示。因此,您将不会有任何机会确定是否使用字面值1.11.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 

这意味着 - 一旦存储为双值,你根据前不同的结果您用于打印价值的cision;这也适用于将小数部分转换为字符串,实际上与以特定精度打印相同。

更糟糕的是,由于暂时不能够以二进制形式精确表示每一个十进制值,两个不同的十进制值可以以二进制形式产生相同的值:

double n1 = 1.1; 
double n2 = 1.100000000000000088817841970012523233890533447265625; 

if (n1 == n2) 
    std::cout << "equal!" << std::endl; 
// Output: equal! 

所以你不能分辨n1n2以上。

了很多的话,和简短的结论:

如果你想从1.10区分1.1,或者如果你通常想找出数字文字的小数部分写在你的源代码,那么你必须将它们存储起来最初为作为字符串,而不是双打。

0

我想你并不熟悉'浮点数'实际是什么。

double是浮点数,如https://en.wikipedia.org/wiki/IEEE_floating_point所述。基本上1.101.1相同,与1.1000000等同。

现在,有一种称为“定点数”的解决方案,通常称为“小数”和“数字”。如果您熟悉数据库引擎,则知道1.10是数字(3,2),1.1是数字(2,1)。注意类型如何改变和定义精度(位数)和缩放比例(逗号后的位数)。但是,C++本身不支持小数。

+0

感谢您的回复,但我不明白这对我有何帮助。你是说我想做什么是不可能的? – brid

+0

@brid,'double'不存储关于有多少数字的信息。所以不,使用简单的双倍是不可能的。您当然可以将其包装在自定义数据结构中,并在解析时添加该信息,或者使用固定点库。 – atlaste

-2

这只是简单的数学。 解析器只是转换你的X.10到X.1 :)