删除ascii浮点数中的小数点而不截断或精度损失

时间:2016-01-29 09:34:16

标签: c floating-point printf string-formatting decimal-point

我在ascii中有一个代表电压的浮点数,例如。 5.625V,我需要删除小数点。我不希望截断数字或松散的精度我只需要没有小数点的数字。

结果编号将插入ascii协议,其字段宽度为5位,表示电压,单位为mV(毫伏)vs V(伏特),如上例所示。该数字需要显示为5个ascii数字,没有十进制表示法。

EG。 ascii中的5.625V浮点数到ascii中的5625 mV十进制数。

看起来很简单......但是不能用优雅的方式来做到这一点。

2 个答案:

答案 0 :(得分:1)

只需转换没有小数部分的毫伏数:

char buffer[32];
float voltage = 5.625;

snprintf(buffer, sizeof buffer, "%.0f", voltage * 1000.);

如果你想用空格填充5个字符,你知道你可以使用的int中的毫伏数适合:

snprintf(buffer, sizeof buffer, "%5d", (int)(voltage * 1000));

如果你应该用前导零填充5个字符,请使用:

snprintf(buffer, sizeof buffer, "%05d", (int)(voltage * 1000));

如果您平台上的int只有16位,则在转换超过float的{​​{1}}时,应使用更大的类型来避免未定义的行为。 INT_MAX保证至少为64位。相应地调整long long格式说明符。

请注意,转换为printfint舍入,如果值超出0的范围,则会调用未定义的行为。如果您知道自己的价值是正数且在范围内,则可以使用int

获得更高的准确度

答案 1 :(得分:1)

问题表明输入是一个ASCII字符串,所以我提出了这个:

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

long s2mv(const char *s)
{
    long mv;
    char *end;
    int sign;

    while (isspace((unsigned char)*s)) {
        s++;
    }

    sign = (*s == '-') ? -1 : 1;
    if (*s == '-' || *s == '+') {
        s++;
    }

    mv = 1000 * strtol(s, &end, 10);
    s = end;
    if (*s++ == '.') {
        int place = 100;

        while (place && isdigit((unsigned char)*s)) {
            mv += place * (*s - '0');
            s++;
            place /= 10;
        }
    }
    return mv * sign;
}

int main(void)
{
    const char *tests[] = {
        "0", "12", "-12", "12.", "-12.", "12.345", "-12.345",
        "1.234", ".123", "0.123", "-0.123", "-.123"
    };
    long mv;
    int i;

    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
        mv = s2mv(tests[i]);
        printf("s2mv(\"%s\") returned %ld\n", tests[i], mv);
    }
    return 0;
}

输出:

s2mv("0") returned 0
s2mv("12") returned 12000
s2mv("-12") returned -12000
s2mv("12.") returned 12000
s2mv("-12.") returned -12000
s2mv("12.345") returned 12345
s2mv("-12.345") returned -12345
s2mv("1.234") returned 1234
s2mv(".123") returned 123
s2mv("0.123") returned 123
s2mv("-0.123") returned -123
s2mv("-.123") returned -123