仅使用标准 C++将任何浮点打印到恰好 N 个空格
我有一个浮点数,我想将其打印到恰好 N 个空格。例如,N = 5。我想打印以下数字:
0.1 => 0.1
123.456789 => 123.5
-123.45678 => -123 (or -123.)
0.123456 => 0.123
123456.789 => 123456 (obviously, in this case, we cannot print less than 6 digits, if I can detect this, I can also print 12** to indicate the field is too wide.
我尝试了多种组合,包括以下内容:
// Leave 3 extra space: One for negative sign, one for zero, one for decimal
std::cout << std::setiosflags(std::ios::fixed)
<< std::setprecision(N - 3)
<< std::setw(N)
<< input;
但结果并不理想。也许我错过了一些明显的东西?
这些示例输入的给定代码的输出是
0.10 // not bad
123.46 // Use 6 instead of 5 spaces
-123.46 // Use 7 instead of 5 spaces
0.12 // Under-use the spaces
123456.79 // Ok, I guess
I have a float that I would like to print to exactly N spaces. For example, with N = 5. I want to get the following numbers printed as so:
0.1 => 0.1
123.456789 => 123.5
-123.45678 => -123 (or -123.)
0.123456 => 0.123
123456.789 => 123456 (obviously, in this case, we cannot print less than 6 digits, if I can detect this, I can also print 12** to indicate the field is too wide.
I have tried many combination including the following:
// Leave 3 extra space: One for negative sign, one for zero, one for decimal
std::cout << std::setiosflags(std::ios::fixed)
<< std::setprecision(N - 3)
<< std::setw(N)
<< input;
But the results are not favorable. Perhaps I am missing something obvious?
The output of the given code for those sample inputs are
0.10 // not bad
123.46 // Use 6 instead of 5 spaces
-123.46 // Use 7 instead of 5 spaces
0.12 // Under-use the spaces
123456.79 // Ok, I guess
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为此,请使用 Boost 的 Spirit.Karma:
在任何情况下,这都会将输出的宽度限制为
5
。如果您想捕获数字被切断的情况(如您的示例中的 123456.7),只需预先执行适当的检查:是的,如果您可能会问,Boost 的 Spirit.Karma 仅使用标准 C++ 编写特征。
Use Boost's Spirit.Karma for this:
which will limit the width of your output to
5
in any case. If you want to catch the case where the number would be cut off (as in your example for 123456.7), just perform the appropriate check up front:And yes, in case you might ask, Boost's Spirit.Karma is written using only Standard C++ features.
[更新]
我应该对提供的所有案例进行测试。 :D
[UPDATE]
I should have tested for all cases provided. :D
您似乎想要打印 N 个字符 - 包括减号(如果有)和小数点。
set precision
只关心小数点后的位数。所以,一点数学知识就能得到你想要的东西:我可能需要解释一下对数线:
0
1
You seem to want to print N characters - including the minus sign (if any) and decimal point.
setprecision
only cares about the number of digits after the decimal point. So, a little math can get you what you want:I probably need to explain the logarithm line:
0
1
iostream 精度/宽度标志不能很好地满足您的要求 - 例如,精度计算有效数字而不是字符位置,并且 4 个请求 0.123456 映射到 0.1234 而不是您请求的 0.123(您愿意吗?)期望 0.00123456 为“0.00”?)。无论如何,要使用精度,您需要根据值改变参数。 如下所示编写自己的函数可能会更容易...
最简单的方法是以额外的精度将值写入字符串流,然后从左到右扫描(记录是否找到 ' .') 直到到达要截断的位置,然后从右向左扫描以删除尾随 0,或者如果“.”则替换为“**”。之前没有遇到过。
否则,您可以实现自己的双精度到 ASCII 转换,可能使用 Linux 的
之类的标头来提供带有上的位字段的
和union
>floatdouble
类型;否则使用您选择的数学运算。Your requirements aren't catered for well by the iostream precision/width flags - for example,
precision
counts significant digits not character positions, and 4 requests 0.123456 be mapped to 0.1234 not the 0.123 you request (would you expect 0.00123456 to be "0.00"?). Anyway, to use precision you'd need to vary the parameter depending on the value. It may be easier to write your own function as below...The easiest way is to write the value to a stringstream with extra precision, then scan left-to-right (recording whether you find a '.') until you reach the point where you'd like to truncate, then scanning right-to-left to remove trailing 0s or to substitute "**" if the "." wasn't encountered earlier.
Otherwise, you can implement your own double-to-ASCII conversion, possibly using a header like linux's
<ieee754.h>
to provide aunion
with bit fields overfloat
anddouble
types; otherwise using mathematical operations of your choice.丑陋,但也许你想要:
Ugly, but perhaps you want: