一种不使用函数库实现C语言gcvt函数功能的代码。
未经过优化,仅供参考。
#include <stdio.h>
#include <math.h>
// 自定义gcvt函数
char *my_gcvt(double value, int ndigit, char *buf)
{
int sign; // 符号标志
int integer, linteger; // 整数部分
double fraction; // 小数部分
int count, k; // 计数器
int i; // 循环变量
// 判断符号
if (value < 0)
{
sign = 1; // 负数
value = -value; // 取绝对值
buf[0] = '-'; // 添加负号
}
else
{
sign = 0; // 正数或零
}
// 判断零
if (value == 0)
{
buf[sign] = '0'; // 添加零字符
buf[sign + 1] = '\0'; // 添加结束符
return buf; // 返回字符串指针
}
// 判断整数
integer = (int)value; // 取整数部分
fraction = value - integer; // 取小数部分
if (fraction == 0)
{
sprintf(buf + sign, "%d", integer); // 直接转换整数部分为字符串
return buf; // 返回字符串指针
}
// 处理小数
if (integer == 0)
{
buf[sign] = '0';
sign++;
count = 0, k = -1; // 初始化计数器
int j;
while (fraction != 0 && count < ndigit)
{ // 循环乘以10直到小数部分为零或者达到最大位数
value *= 10; // 乘以10
integer = (int)value; // 取整数部分
fraction = value - integer; // 取小数部分
count++; // 计数器加一
}
// 处理四舍五入
if (fraction >= 0.5)
{ // 如果小数部分大于等于0.5,就进位
integer++; // 整数部分加一
if (integer == pow(10, count))
{ // 如果整数部分等于10的count次方,说明进位后多了一位
count++; // 计数器加一
}
}
linteger = integer;
while (integer > 0)
{
integer /= 10; // 将num除以10
k++; // 将len加一
}
j = k + 1;
for (k; k < count; k++)
{
buf[sign + k - 1] = '0';
}
// 转换为字符串
sprintf(buf + sign + count - j, "%d", linteger); // 转换整数部分为字符串
// 插入小数点
for (i = sign + count; i > sign; i--)
{ // 从后往前移动count位字符,空出一位插入小数点
buf[i] = buf[i - 1];
}
buf[sign] = '.'; // 插入小数点
// 删除末尾的小数点或空格(如果有的话)
i = sign + count + 1; // 定位到末尾字符的位置
while (buf[i] == '.' || buf[i] == ' ')
{ // 如果是小数点或空格,就删除它
buf[i] = '\0';
i--;
}
buf[i + 1] = '\0';
// printf("%d\n",k);
return buf; // 返回字符串指针
}
count = 0, k = 0; // 初始化计数器
while (fraction != 0 && count < ndigit)
{ // 循环乘以10直到小数部分为零或者达到最大位数
value *= 10; // 乘以10
integer = (int)value; // 取整数部分
fraction = value - integer; // 取小数部分
count++; // 计数器加一
}
// 处理四舍五入
if (fraction >= 0.5)
{ // 如果小数部分大于等于0.5,就进位
integer++; // 整数部分加一
if (integer == pow(10, count))
{ // 如果整数部分等于10的count次方,说明进位后多了一位
count++; // 计数器加一
}
}
// 转换为字符串
sprintf(buf + sign, "%d", integer); // 转换整数部分为字符串
while (integer > 0)
{
integer /= 10; // 将num除以10
k++; // 将len加一
}
// 插入小数点
for (i = sign + k; i > (sign + k) - count; i--)
{ // 从后往前移动count位字符,空出一位插入小数点
buf[i] = buf[i - 1];
}
buf[i] = '.'; // 插入小数点
// 删除末尾的小数点或空格(如果有的话)
i = sign + k + 1; // 定位到末尾字符的位置
while (buf[i] == '.' || buf[i] == ' ')
{ // 如果是小数点或空格,就删除它
buf[i] = '\0';
i--;
}
buf[i + 1] = '\0';
return buf; // 返回字符串指针
}
// 测试函数
int main(void)
{
double num; // 测试用的浮点数
int ndigit; // 测试用的显示位数
char str[20]; // 测试用的字符串缓冲区
num = -3.1415; // 赋值
ndigit = 4; // 赋值
my_gcvt(num, ndigit, str); // 调用自定义函数
printf("num = %f, ndigit = %d, str = %s\n", num, ndigit, str); // 输出结果
num = 0.12300; // 赋值
ndigit = 4; // 赋值
my_gcvt(num, ndigit, str); // 调用自定义函数
printf("num = %f, ndigit = %d, str = %s\n", num, ndigit, str); // 输出结果
num = 4e5; // 赋值
ndigit = 5; // 赋值
my_gcvt(num, ndigit, str); // 调用自定义函数
printf("num = %f, ndigit = %d, str = %s\n", num, ndigit, str); // 输出结果
return 0;
}