输出浮点数而不以零结尾的 sprintf() 模式是什么?
我想输出没有结尾零的浮点数。
示例:float 3.570000 应输出为 3.57
,float 3.00000 应输出为 3.0(所以这里是例外!)
I want to output my floats without the ending zeros.
Example: float 3.570000 should be outputted as 3.57
and float 3.00000 should be outputted as 3.0 (so here would be the exception!)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
paxdiablo 的 morphNumericString() 的更高效且(在我看来)更清晰的形式。抱歉没有编译或测试。
A more efficient and (in my opinion) clearer form of paxdiablo's morphNumericString(). Sorry not compiled or tested.
这对于标准 printf 语义来说是不可能的。在过去,我必须通过输出到一个字符串(类似于
"%.20f"
)然后对字符串进行后处理来完成此操作。您可能正在寻找这样的东西:
代码遍历每个参数,依次改变每个参数。以下记录显示了它的工作原理:
但是您应该注意,如果使用浮点数或双精度数,则必须注意正常的浮点误差。在我的系统上3.57实际上是3.5699999999999998401,它根本不会被截断。
当然,您可以通过在 sprintf 中使用不太具体的输出位数(低于浮点的实际精度)来解决该问题。例如,我的系统上的
"%.10f"
输出 3.5700000000,将被截断。将以下行添加到main
:将导致以下添加的输出:
根据您的测试数据。
另一种可能性(如果您的输入范围和精度可以控制)是使用
g
格式说明符。它以f
格式输出,其中精度是最大位数(而不是像f
这样的固定数字)或指数格式(f
) >e)。基本上,只要显示所有信息,它就更喜欢非指数输出格式。仅当能够提供更多信息时,它才会切换为指数。一个简单的示例是带有
3.7
和.0000000004
的格式字符串"%.4g"
。前者将打印为3.7
,后者将打印为4e-10
。更新:对于那些更关心性能而不是鲁棒性或可读性的人,您可以尝试以下方法(我认为不必要,但对每个人来说
都是如此):它可能更快,但是,考虑到我所见过的现代编译器所做的极端优化,你永远不会太确定。我倾向于首先考虑可读性,只有在速度成为问题时才担心速度(YAGNI 可以同样适用于性能和功能)。
This is not possible with standard printf semantics. In, the past, I've had to do this by outputting to a string (with something like
"%.20f"
) then post-processing the string.Something like this is probably what you're looking for:
The code runs through each of it's arguments, morphing each one in turn. The following transcript shows how it works:
You should be aware however that, if using floats or doubles, you'll have to watch out for the normal floating point inaccuracies. On my system 3.57 is actually 3.5699999999999998401, which won't be truncated at all.
Of course, you can get around that problem by using a less-specific number of output digits in the
sprintf
, something less than the actual accuracy of the floating point point. For example,"%.10f"
on my system outputs 3.5700000000 which will be truncated. Adding the following lines tomain
:will result in the following added output:
as per your test data.
One other possibility (if your input range and precision can be controlled) is to use the
g
format specifier. This outputs in eitherf
format where the precision is the maximum number of digits (rather than fixed number likef
) or exponential format (e
).Basically, it prefers the non-exponential output format as long as all the information is shown. It will switch to exponential only if that will deliver more information. A simple example is the format string
"%.4g"
with3.7
and.0000000004
. The former would be printed as3.7
, the latter as4e-10
.Update: for those more concerned about performance than robustness or readability, you could try the following (unnecessary in my opinion but to each their own):
It may be faster but, given the extreme optimisations I've seen modern compilers do, you can never be too sure. I tend to code for readability first and only worry about speed when it becomes an issue (YAGNI can apply equally to performance as well as functionality).
我的方法是:
实现一个函数trim(char c)来消除尾部'c',例如:
void Trim(std::string &str, char c) {
size_t len = str.length();
}
char buf[32];
printf(buf, "%f", 0.01);
std::string s(buf);
修剪(buf,'0');
My approach is:
implement a function trim(char c) to eliminate the trail 'c', for examaple:
void trim(std::string &str, char c) {
size_t len = str.length();
}
char buf[32];
printf(buf, "%f", 0.01);
std::string s(buf);
trim(buf, '0');
当输入以小数点结尾时,这将失败,但在大多数情况下,它会适当截断(或追加)。
This will fail when the input ends with a decimal point, but for the most part, it will truncate (or append) appropriately.
这是另一个字符串修改函数。我确实测试过。
它比 Bill 和 Diablo 的长,但它可以处理尾随 9 和 0,并且应该表现良好。
在点后留下一个尾随零。您必须使用
sprintf
进行截断才能获得正确的尾随 9。编辑: 哎呀,输入 999.999 时会失败。留给读者作为练习;v)
Here's another string modification function. I did test it.
It's longer than Bill's and Diablo's, but it handles trailing 9's as well as 0's and should perform well.
Leaves a single trailing zero after the dot. You'll have to truncate using
sprintf
to get proper trailing 9's.Edit: Yikes, this fails on input like 999.999. Left as an exercise to the reader ;v)
直接计算小数部分可能会更容易:
fractional_magnitude/fractional_scale
将是四舍五入到significant_digits
sig Figs 的分数。即使使用双打,也保证不会溢出。格式化分数应该很简单。
It might be easier to calculate the fractional part directly:
fractional_magnitude/fractional_scale
will be the fraction rounded tosignificant_digits
sig figs. Even with doubles, this is guaranteed not to overflow.Formatting the fraction should be straightforward.