我使用MPFR库对大数字进行计算,但也返回小数点后8位数的双精度。
我mpfr_sprintf一个char数组的数字,所以精度或任何东西都不会丢失。 一切都很好,除了我没有在文档中找到任何千位分隔符选项(或者我错过了它)。
鉴于 20043.95381376 之类的数字,我想将其表示为 20,043.95381376 以提高可读性。
或 164992818.48075795 为 164,992,818.48075795
我读到了应该添加到printf / sprintf的撇号,但这似乎是UNIX / POSIX的东西而且我是Windows用户。
由于我在内部将数字打印为字符串,我认为我能做的是编写一个自定义实现,根据数字(> 1000> 10000> 100000等)自动添加逗号,但后来我意识到像strncpy或strcpy这样的函数基本上会替换,而不是将逗号添加到所需的位置。以下是关于如何做到这一点的方法。
我该怎么做?
答案 0 :(得分:2)
您需要实现将double值转换为string并检查该字符串的每个字符,然后将其与分隔符一起复制到输出字符串。
这样的事情:
#include <stdio.h>
#include <string.h>
int thousandsep(double in, char* out_str, size_t out_len, unsigned int precision) {
char in_str[128], int_str[128], format[32];
size_t dlen, mod, i, j;
int c;
snprintf(format, sizeof format, "%%.%df", precision);
snprintf(in_str, sizeof in_str, format, in);
snprintf(int_str, sizeof int_str, "%d", (int)in);
dlen = strlen(in_str);
mod = strlen(int_str) % 3;
c = (mod == 0) ? 3 : mod;
for (i=0, j=0; i<dlen; i++, j++, c--) {
if (j >= out_len - 1) {
/* out_str is too small */
return -1;
}
if (in_str[i] == '.') {
c = -1;
} else if (c == 0) {
out_str[j++] = ',';
c = 3;
}
out_str[j] = in_str[i];
}
out_str[j] = '\0';
return 0;
}
然后像这样使用它:
char out_str[64];
if (thousandsep(20043.95381376, out_str, sizeof out_str, 8) == 0)
printf("%s\n", out_str); /* 20,043.95381376 */
if (thousandsep(164992818.48075795, out_str, sizeof out_str, 8) == 0)
printf("%s\n", out_str); /* 164,992,818.48075795 */
if (thousandsep(1234567.0, out_str, sizeof out_str, 0) == 0)
printf("%s\n", out_str); /* 1,234,567 */
注意:我认为如果你在Windows上,你可能正在使用MSVC,所以这个解决方案应该在C89编译器上工作。
答案 1 :(得分:2)
GetNumberFormatEx
将采用数字的纯字符串版本,并使用分组分隔符,适当的小数点等格式化它。将LOCALE_NAME_USER_DEFAULT
作为语言环境传递,它将采用以下格式:用户更喜欢。
如果您需要覆盖其中一个设置(例如精度),则可以populate a NUMBERFMT struct with the defaults然后更改需要控制的字段。
答案 2 :(得分:0)
似乎没有可以使用的格式化指令。
这是一种快速而又脏的方法,即获取包含浮点数的字符串并将逗号插入适当的位置。
这使用了几个临时缓冲区。千位分隔符符号将取决于区域设置,小数点符号也是如此。但是,对于此示例,逗号是硬编码的。
这基本上只取浮点数的字符串表示,然后逐步将数字复制到另一个缓冲区并在适当的位置插入逗号。
你也可以用更少的缓冲区来看看这个,就像我说的那样,这很快,很脏,而且效率不高。
{
double dFloat = 123456789012.567890;
char xBuff[128];
sprintf (xBuff, "%f", dFloat);
char xBuff2[128];
int iLen = strlen(xBuff);
int iPoint = iLen;
for (iLen--; iLen >= 0; iLen--) {
if (xBuff[iLen] == '.' || xBuff[iLen] == ',') {
// found the decimal point. depends on locale.
iPoint = iLen;
break;
}
}
strcpy (xBuff2, xBuff + iPoint); // save the decimal portion
char xBuff3[128], xBuff4[128];
xBuff3[127] = 0; // set an end of string
int iCount, jLen;
for (iCount = 1, jLen = 126, iLen--; iLen >= 0; jLen--, iLen--) {
if ((iCount % 4) == 0) {
xBuff3[jLen] = ',';
jLen--;
iCount = 1;
}
xBuff3[jLen] = xBuff[iLen];
iCount++;
}
strcpy (xBuff4, xBuff3 + jLen + 1);
strcat (xBuff4, xBuff2);
}
答案 3 :(得分:0)
#include <stdio.h>
#include <locale.h>
int main(void)
{
setlocale(LC_NUMERIC, "");
printf("%'.8lf\n", 164992818.48075795);
return 0;
}