把很小的数,它接近0但不等于0
通过计算过程中,会有精度丢失的可能!
解决的方法:把浮点数 字符串化,这样精度就不会丢失了
文件读取 | sprintf() | 自写函数 | ecvt()函数 |
---|---|---|---|
效果最好 | 效果最好 | 效果好 | 效果稍差 |
速度快 | 几乎没有限制 速度快 |
限制多 | 限制少 |
效果最好
见 https://blog.csdn.net/qq_40893824/article/details/105997362 1.3.1 小节
sprintf 跟 printf 用法上区别:
前者打印到字符串中
后者直接在命令行上输出
效果最好,速度还快,不知道复杂度是多少
解析:
int sprintf(char *string, char *format [,argument,...]);
int j = sprintf( buffer, " String: %s\n", s);
j = 返回写入的字符总数
buffer = string
" String: %s\n" = char *format
, s = [,argument,...]
基本使用代码:
#include
#define num 100
using namespace std;
int main()
{
char buffer[num], s[] = "123456", c = 'd' ;
int i = 35, j, a = 1;
float f = 3.1415926f;
j = sprintf(buffer, "str[] = %s\n", s);
printf("第%d次:\n%s\n字符长度 j = %d\n\n\n", a++, buffer, j);
j += sprintf(buffer + j, "c = %c\n", c);
printf("第%d次:\n%s\n字符长度 j = %d\n\n\n", a++, buffer, j);
j += sprintf(buffer + j, "i = %d\n", i);
printf("第%d次:\n%s\n字符长度 j = %d\n\n\n", a++, buffer, j);
j += sprintf(buffer + j, "f = %f\n", f);
printf("第%d次:\n%s\n字符长度 j = %d\n\n\n", a++, buffer, j);
system("pause");
return 0;
}
#include
#define num 180000
using namespace std;
int main()
{
char buffer[num];
int j;
long double f = LDBL_MIN;
j = sprintf(buffer, " LBDL_MIN = %-18000.17000Lf\n", f);
printf("%-18000.17000s", buffer);
system("pause");
return 0;
}
效果对比见 2.5
思路:
注意正负号的处理!
#include
#define num 100000
using namespace std;
typedef struct
{
char data[num];
int length1, length2;
}Str;
void init(Str &str) // 初始化
{
memset(str.data, '\0', sizeof(str.data[0]));
str.length1 = str.length2 = 0;
}
void change(char str[], int low, int high) // low - high交换
{
while(low < high)
{
str[low] = str[low] + str[high];
str[high] = str[low] - str[high];
str[low] = str[low] - str[high];
low ++;
high--;
}
}
void print(Str str) // 输出 str 的信息
{
int i;
for(i = 0; i <= str.length2; i++)
cout << str.data[i];
cout << endl;
if(str.data[0] == '-')
{
cout << "整数部分长度 = " << str.length1 - 1 << endl;
cout << "小数部分长度 = " << str.length2 - str.length1 - 1 <<endl << endl;
}
else
{
cout << "整数部分长度 = " << str.length1 << endl;
cout << "小数部分长度 = " << str.length2 - str.length1 - 1 <<endl << endl;
}
}
int main()
{
long double number, temp;
long long int_t, low;
int m, n, i;
Str str;
FILE *fp;
init(str); //初始化
number = LDBL_MIN;
cout << "number = LDBL_MIN = " << number << endl << endl;
if(number == 0)
{
str.data[0] = '0';
str.data[1] = '\0';
str.length1 = 1;
str.length2 = 0;
}
else
{
i = 0;
if(number < 0) //带负号
{
str.data[0] = '-';
i = 1;
}
int_t = (long long)number; // int_t 整数部分
temp = number - int_t; // temp 小数部分
if(temp < 0)
temp = -temp;
cout << "int_t = "<< int_t<< endl;
cout << "temp = "<< temp<< endl;
if(int_t == 0)
{
str.data[i] = int_t + '0';
i++;
str.length1 = 1;
}
else
{
while(int_t != 0)
{
str.data[i] = int_t%10 + '0';
i++;
int_t /= 10;
cout << i <<" ";
}
str.length1 = i;
cout << "123"<< endl;
}
if(str.data[0] == '-')
low = 1;
else
low = 0;
change(str.data, low, i-1);
str.data[i] = '.';
cout << "123"<< endl;
while(temp != 0)
{
//cout << "123"<< endl;
i++;
int_t = temp*10 ;
str.data[i] = int_t%10 + '0';
temp = temp*10 - int_t%10;
}
cout << "123"<< endl;
str.length2 = i;
str.data[i] = '\0';
}
cout << "str = ";
print(str);
fp = fopen("./range.txt", "w+");
fputs(str.data, fp);
fclose(fp);
system("pause");
return 0;
}
char* ecvt(double value, int ndigit, int *decpt, int *sign);
把一个双精度浮点数转换成一个字符串。
#include
#define num 18000
using namespace std;
void change(char str[], int low, int high)
{
while(low < high)
{
str[low] = str[low] + str[high];
str[high] = str[low] - str[high];
str[low] = str[low] - str[high];
low ++;
high--;
}
}
int main()
{
double number;
long double number2;
long long temp;
int dec, sign;
char *str;
cout << "DBL_MIN = " << DBL_MIN << endl;
str = ecvt(DBL_MIN, num, &dec, &sign);
cout << "str = " << str << endl ;
cout << "dec = " << dec << endl;
cout << "sign = " << sign << endl <<endl;
cout << "LDBL_MIN = " << LDBL_MIN << endl;
str = ecvt(LDBL_MIN, num, &dec, &sign);
cout << "str = " << str << endl ;
cout << "dec = " << dec << endl;
cout << "sign = " << sign << endl <<endl;
system("pause");
return 0;
}
上:自写函数;下:ecvt()函数
和 sprintf() 比较的话…
可以看到,自己编写的函数得到的有效数字 要比 ecvt()函数要多一些,但远远不如 sprintf()!
ecvt() 读不了LDBL_MIN,但自己写的函数勉强可以