可以所做的就是将 sprintf("%.20g")的数字转换为一个字符串缓冲区,然后操作该字符串使其只包含超过小数点的 N 个字符。
假设您的数字在变量 num 中,下面的函数将删除除了第一个 N小数以外的所有小数,然后去掉后面的零(如果它们都是零,则去掉小数点)。
char str[50];
sprintf (str,"%.20g",num); // Make the number.
morphNumericString (str, 3);
: :
void morphNumericString (char *s, int n) {
char *p;
int count;
p = strchr (s,'.'); // Find decimal point, if any.
if (p != NULL) {
count = n; // Adjust for more or less decimals.
while (count >= 0) { // Maximum decimals allowed.
count--;
if (*p == '\0') // If there's less than desired.
break;
p++; // Next character.
}
*p-- = '\0'; // Truncate string.
while (*p == '0') // Remove trailing zeros.
*p-- = '\0';
if (*p == '.') { // If all decimals were zeros, remove ".".
*p = '\0';
}
}
}
一个简单的解决方案,但它完成了工作,分配了一个已知的长度和精度,并避免了指数格式(当您使用% g 时,这是一个风险)的机会:
// Since we are only interested in 3 decimal places, this function
// can avoid any potential miniscule floating point differences
// which can return false when using "=="
int DoubleEquals(double i, double j)
{
return (fabs(i - j) < 0.000001);
}
void PrintMaxThreeDecimal(double d)
{
if (DoubleEquals(d, floor(d)))
printf("%.0f", d);
else if (DoubleEquals(d * 10, floor(d * 10)))
printf("%.1f", d);
else if (DoubleEquals(d * 100, floor(d* 100)))
printf("%.2f", d);
else
printf("%.3f", d);
}
void stripTrailingZeros(void) {
//This finds the index of the rightmost ASCII char[1-9] in array
//All elements to the left of this are nulled (=0)
int i = 20;
unsigned char char1 = 0; //initialised to ensure entry to condition below
while ((char1 > 57) || (char1 < 49)) {
i--;
char1 = sprintfBuffer[i];
}
//null chars left of i
for (int j = i; j < 20; j++) {
sprintfBuffer[i] = 0;
}
}
我需要这个 PaxDiablo 的第一个回答就能解决问题。但是我不需要截断和下面的版本可能稍微快一点?
开始搜索字符串末尾(EOS)后的“ .”,只有一个 EOS 的位置。
//https://stackoverflow.com/questions/277772/avoid-trailing-zeroes-in-printf
//adapted from paxdiablo (removed truncating)
char StringForDouble[50];
char *PointerInString;
void PrintDouble (double number) {
sprintf(StringForDouble,"%.10f",number); // convert number to string
PointerInString=strchr(&StringForDouble[0],'.'); // find decimal point, if any
if(PointerInString!=NULL) {
PointerInString=strchr(&PointerInString[0],'\0'); // find end of string
do{
PointerInString--;
} while(PointerInString[0]=='0'); // remove trailing zeros
if (PointerInString[0]=='.') { // if all decimals were zeros, remove "."
PointerInString[0]='\0';
} else {
PointerInString[1]='\0'; //otherwise put EOS after the first non zero char
}
}
printf("%s",&StringForDouble[0]);
}