Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C printf double在可用宽度内具有最大精度_C_Printf_Double_Precision - Fatal编程技术网

C printf double在可用宽度内具有最大精度

C printf double在可用宽度内具有最大精度,c,printf,double,precision,C,Printf,Double,Precision,我需要用C打印两个字符,宽度为20,但使用20个字符可以打印的最大精度 例如: -123.123456789123456789 应打印: -123.1234567891234568 到目前为止,我有以下代码可以工作,但很难看,存在问题: double num = .......; int pr = 0; char temp[32] = { 0 }; char *point = NULL; sprintf(temp, "%.20f", num); point = strchr(temp, '

我需要用C打印两个字符,宽度为20,但使用20个字符可以打印的最大精度

例如:

-123.123456789123456789 
应打印:

-123.1234567891234568
到目前为止,我有以下代码可以工作,但很难看,存在问题:

double num = .......;
int pr = 0;
char temp[32] = { 0 };
char *point = NULL;
sprintf(temp, "%.20f", num);
point = strchr(temp, '.');
if (point) {
    pr = 20 - (1 + point - temp);
}
printf("%20.*f", pr, num);
问题是这不适用于%g而不是%f,它有时打印超过20个字符,即使不存在指数部分。 当给出0.000123456789123456789这样的数字时,就会出现问题。小数点后的额外零似乎不算(!)。

根据和的一些提示,我实现了以下似乎有效的解决方案。 我不再尝试预先计算要使用的正确精度,而是以足够的精度打印,然后裁剪多余的数字

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void printDouble(double val, int width)
{
    char *temp = malloc((width + 32) * sizeof(char));
    int len = 0;
    sprintf(temp, "%*.*g", width, width, val);
    len =strlen(temp);
    if (len > width) {
        char *dropped = temp + width;
        char *last = dropped - 1;
        char *expon = strchr(temp, 'E');
        if (!expon)
            expon = strchr(temp, 'e');
        if (expon) {
            last = temp + width - 1 - strlen(expon);
            dropped = last + 1 < expon ? last + 1 : NULL;
        }
        if (strchr(temp, '.')) {
            /* Round */
            if (dropped && *dropped >= '5' && *dropped <= '9') {
                while (*last == '9')
                    last--;
                (*last)++;
            }
            /* Remove trailing zeroes */
            while (*last == '0')
                last--;
        }
        if (expon) {
            while (*expon != '\0')
                *(++last) = *(expon++);
        }
        *(++last) = '\0';
    }
    printf("%*s\n", width, temp);
    free(temp);
}
#包括
#包括
#包括
静态无效printDouble(双值,整数宽度)
{
char*temp=malloc((宽度+32)*sizeof(char));
int len=0;
sprintf(温度,“%*.*g”,宽度,宽度,val);
len=strlen(温度);
如果(长度>宽度){
字符*删除=温度+宽度;
char*last=dropped-1;
char*expon=strchr(temp,'E');
如果(!expon)
expon=strchr(温度,'e');
如果(expon){
最后一个=温度+宽度-1-标准长度(expon);
DROPED=last+1如果(dropped&&*dropped>='5'&&&*dropped“问题是,这不适用于%g而不是%f。”不够好。要准确。它怎么不起作用呢?虽然另一篇文章的OP不关心这个问题,但这正是这个OP想要的-我认为。问题是存在一些小情况,使得使用预先计算的格式不是最佳的。链接的答案尝试了各种
“%.*e”
解决方案。为什么希望输出为
-123.123456789123456
而不是更精确的
-123.123456789123457
?(勾选最后一位)1)“打印双精度C,宽度为20”-->如何打印可能需要300多个数字的
DBL_MAX
之类的
double
?还是要跳转到指数记数法?2)是否应在+123.12345678123456789上再打印一个小数位,如
“123.123456781234567”
“%g”
“使用可打印的最大精度”要求,但通过一个几乎相似的标准跳到指数级。更重要的是:最大精度、易于编码、所有
双精度