Arduino 将小数点位置添加到long

Arduino 将小数点位置添加到long,arduino,arduino-esp8266,Arduino,Arduino Esp8266,我有一个长值,我想把它转换成3的小数 样本值: 324 4353 53463 如果值的长度为3,则这些数字是小数,如:324应为0.324 如果它有4个以上的位置,最后3个数字是小数,例如:4353应该是4.353,53463应该是53.463 做这件事最好的方法是什么。。。我是否应该将其转换为字符串并使用字符串操作来添加。或者有没有更简单的方法来做到这一点(似乎不正确) 看来您的整个问题可以总结如下: 您有一个long要转换为double并除以1000 因此,正如人们在评论中所解释的,x/10

我有一个长值,我想把它转换成3的小数

样本值: 324 4353 53463

如果值的长度为3,则这些数字是小数,如:324应为0.324

如果它有4个以上的位置,最后3个数字是小数,例如:4353应该是4.353,53463应该是53.463


做这件事最好的方法是什么。。。我是否应该将其转换为字符串并使用字符串操作来添加。或者有没有更简单的方法来做到这一点(似乎不正确)

看来您的整个问题可以总结如下:

您有一个
long
要转换为
double
并除以1000

因此,正如人们在评论中所解释的,
x/1000.0
应该做到这一点


如果您只想用
来显示它,而实际上您不需要使用
双精度
,那么将
长的
转换为字符串,预先加上一些零,并在字符串中嵌入
字符也可以,特别是因为这是一个arduino,可能没有任何国际化顾虑。(如果您确实有国际化方面的顾虑,那么您应该使用
double
,因为您的标准库将使用
或适合当前文化的任何内容来显示它。)

这种技术称为缩放。只需将数字视为乘以10^(小数位数)

示例:小数点后两位:457657856表示4576578.56

4小数位56表示0.0056

x和y按小数点后n位缩放,w和z表示实数

x+y=w+z

x-y=x-z

(x*y)/10^n=w*z

(x*10^n)/y=w/z

从字符串中读取-您有关于它的1e10 SO主题

我有一个长值,我想把它转换成3的小数

根据此注释和OP的其他注释,其显示为字符串或需要打印输出

long some_long = foo();
double d = some_long / 1000.0;
printf("%.3f\n", d);
名义上,以下内容将实现这一点。请注意,
d
的值可能仅接近0.001的数学倍数,但并不精确。然而,
printf()
将根据需要打印一个舍入值

long some_long = foo();
double d = some_long / 1000.0;
printf("%.3f\n", d);

但是当
long
中的值位超过
double
的二进制精度时会发生什么情况

分两部分打印。处理负值很棘手:一定要打印符号,使用最大值和最小值的绝对值,并打印前导零

long some_long = foo();
long most = some_long / 1000;
long least = some_long % 1000;
printf("%s%ld.%03ld\n", "-" + (some_long >= 0), labs(most), labs(least));

[到维基-不在其中获取积分]

以下是一个简单的正负值解决方案:

#include <limits.h>
#include <stdio.h>

void print_long_3decimals(long value) {
    char buf[CHAR_BIT * sizeof(long) / 3 + 2];
    int len = sprintf(buf, "%04ld", value);
    printf("%*s.%s\n", len - 3, buf, buf + len - 3);
}
#包括
#包括
无效打印长度3个字符(长值){
char buf[char_BIT*sizeof(long)/3+2];
int len=sprintf(buf,“%04ld”,值);
printf(“%*s.%s\n”,len-3,buf,buf+len-3);
}
下面是另一个用于转换为具有指定小数位数的字符串的方法:

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

// assuming dest is sufficiently large
char *convert_long_decimals(char *dest, long value, int decimals) {
    int n = decimals > 0 ? decimals : 0;
    char *p = dest + sprintf(dest, "%0*ld", n + 1, value) - n;
    if (n) {
        memmove(p + 1, p, n + 1);
        *p = '.';
    }
    return dest;
}
#包括
#包括
//假设dest足够大
char*convert\u long\u小数(char*dest,long value,int小数){
int n=小数>0?小数:0;
char*p=dest+sprintf(dest,“%0*ld”,n+1,值)-n;
如果(n){
memmove(p+1,p,n+1);
*p=';
}
返回目的地;
}

hm.
(double)x/1000.0
?您尚未指定需要结果的形式,这取决于您希望对其执行的操作。您想要字符串
“0.324”
,还是要打印该字符序列?还是浮点值?或者代码将解释为数值0.324的整数值?@EugeneSh。
(double)
甚至不是必需的,因为您正在被一个
double
除法
x/1000.0
工作正常。@Kevin我不确定使用
double
的哪一面,所以我都做了:)因为
double
没有小数位数的概念,所以您必须转换为字符串。用
long i=n/1000
long d=n%1000
将数字
long n
分成两部分,然后用
sprintf
创建一个字符串(或直接用
printf
打印),使用这两部分,宽度和填充说明符(视情况而定)用
分隔。
。但是,这不是一个“GimMethe Cordz”站点。如果你要在一个字符串中嵌入<代码> ./COD>,有几个拐角的情况需要考虑。如果输入小于1000,则需要添加前导
0
s。如果是负数,你必须处理
-
符号。@Keith Thompson为什么。如果在整数中缩放4位小数,则0.0056由56表示。没有前导零needed@KeithThompson是。@PeterJ:我指的是上一段中的建议,将整数转换为字符串,然后插入一个
字符。(在我的评论之后添加了“prepending some zero”子句。)有一个精度问题:
double
只有53位尾数,而
long
可能有63位值。您的解决方案在许多非常大的
long
值上失败。
printf(“%ld.%03ld\n”,most,labs(least))不适用于
some_long=-100。它打印
0.100
。可能的修复方法是:
printf(“%s%ld.%03ld\n”、“-”+(某些长度>=0)、实验室(大多数)、实验室(最少))你能找到一个更优雅的解决方案吗?@chqrlie Hmmm。很好的捕获-让我想起我做过的其他需要检查的代码。这是wiki,请随意编辑。@chux我正试图将您的解决方案组合到一个函数中。如何返回printf的结果?当我以
return printf(“%s%ld.%03ld\n”、“-”+(some_long>=0)、labs(most)、labs(least))结束函数时返回字符数。@svh1985“如何返回printf的结果?”&&“它返回字符数”-->这是
printf()的结果。如果那不是你想要的