【发布时间】:2016-01-19 18:18:14
【问题描述】:
我一整天都在为这个难以解决的小问题而烦恼,我很确定在表面下发生了一些我不知道的事情。非常欢迎任何反馈或帮助。
我有一个函数,它接受一个浮点值并返回一串 ASCII 字符以输出到 LCD 屏幕上。函数如下:
char returnString(float x, bool isTriggTemp)
{
char numberString[3];
char bufferString[2];
char bufferStringDec[7];
int integerVal = (int)x;
if(isTriggTemp == false)
{
int decimalVal = (x-integerVal)*10000;
sprintf(numberString, "%s.%s", itoa(bufferString,integerVal,10),
itoa(bufferStringDec,decimalVal,10));
}
else
{
int decimalVal = (x-integerVal)*1000;
sprintf(numberString, "%s.%s", itoa(bufferString,integerVal,10),
itoa(bufferStringDec,decimalVal,10));
}
return numberString;
}
If 语句和 bool 的原因是有两个浮点数可以传递给函数。一个有 1 个小数位,一个有 5 个小数位。我不会对小数点后 5 个数字大惊小怪,因为我稍后会在程序中比较两个浮点数,并且相关的小数似乎大致一致。
我的查询源于这一行:
int decimalVal = (x-integerVal)*10;
当像这样使用时,考虑到上述逻辑,这是我期望必须使用的,无论 X 值如何,输出的字符串都会读取“X.0”。
将其增加到 100:
int decimalVal = (x-integerVal)*100;
仅给出偶数的正确值。 (当浮点数为 X.2 时,X.2 很好),但是对于奇数,我似乎得到了一个向下舍入的版本(X.3 浮点数打印 X.2,X.5 -> X.4)等等。
当我把它增加到 1000 时,我开始看到问题的开始:
int decimalVal = (x-integerVal)*1000;
对于偶数值,例如 X.4,我会打印 X.40。对于奇数,我得到的比原来的浮点数少 0.01。例如。 X.5 - > X.49。
显然这里有问题,不精确的小数被截断了。 A)我该如何解决这个问题?和 B) 考虑到算术,我猜应该使用 *10 但 *100 是 10 的数量级,它使我最接近正确的输出。
非常感谢任何帮助。
【问题讨论】:
-
为什么要使用复杂的方法来写出 %f?
-
另外,您返回的类型错误。
-
您需要在四舍五入之前添加一半的分辨率。所以如果你要四舍五入到最接近的 0.01,你需要先加上 0.005。
-
逻辑似乎在努力避免直接解决方案,例如
sprintf (buf, "%6.1f", x)。为什么? -
我认为这是我被规定的方式,我正在处理的设备接受 char 变量的返回,并且我的写入 LCD 方法可以使用它。我不确定以这种方式返回类型的原因,但这是我被告知的方式,它一直运行良好。这是否是正确的编码实践是另一回事,因此感谢您的反馈。 @GeorgeHoupis 我还将研究仅使用浮点值来简化 sprint() ,我不知道我可以使用具有不同小数位的多个浮点数来做到这一点。
标签: c casting floating-point precision