C 以不带整数部分的科学格式打印双精度
一个简单的问题,但我无法获得关于这种格式的文档:我想用Fortran科学记数法打印一个浮点,其整数部分始终为零C 以不带整数部分的科学格式打印双精度,c,double,scientific-notation,C,Double,Scientific Notation,一个简单的问题,但我无法获得关于这种格式的文档:我想用Fortran科学记数法打印一个浮点,其整数部分始终为零 printf("%0.5E",data); // Gives 2.74600E+02 我想这样打印: .27460E+03 如何才能使这个结果尽可能清晰?我尝试使用log10()和pow()进行此操作,但最终遇到舍入错误问题。因此,正如所评论的,字符串操作可能是最好的方法 #include <stdlib.h> char *fortran_sprintf_doub
printf("%0.5E",data); // Gives 2.74600E+02
我想这样打印:
.27460E+03
如何才能使这个结果尽可能清晰?我尝试使用
log10()
和pow()
进行此操作,但最终遇到舍入错误问题。因此,正如所评论的,字符串操作可能是最好的方法
#include <stdlib.h>
char *fortran_sprintf_double(double x, int ndigits) {
char format[30], *p;
static char output[30];
/* Create format string (constrain number of digits to range 1–15) */
if (ndigits > 15) ndigits = 15;
if (ndigits < 1) ndigits = 1;
sprintf(format, "%%#.%dE", ndigits-1);
/* Convert number to exponential format (multiply by 10) */
sprintf(output, format, x * 10.0);
/* Move the decimal point one place to the left (divide by 10) */
for (p=output+1; *p; p++) {
if (*p=='.') {
*p = p[-1];
p[-1] = '.';
break;
}
}
return output;
}
#包括
char*fortran\u sprintf\u double(双x,整数ndigit){
字符格式[30],*p;
静态字符输出[30];
/*创建格式字符串(将位数限制在1到15之间)*/
如果(ndigits>15)ndigits=15;
如果(ndigits<1)ndigits=1;
sprintf(格式,“%%#.%dE”,NDIGTS-1);
/*将数字转换为指数格式(乘以10)*/
sprintf(输出,格式,x*10.0);
/*将小数点向左移动一位(除以10)*/
对于(p=输出+1;*p;p++){
如果(*p='。){
*p=p[-1];
p[-1]=';
打破
}
}
返回输出;
}
如果您只关心整数部分是0
,而不是真正忽略0
,也就是说,如果您对0.27460E+03
而不是.27460E+03
很满意,您可以做类似的事情:
#include <stdio.h>
#include <stdlib.h>
void fortran_printf();
int main(void)
{
double num = 274.600;
fortran_printf(num);
exit(EXIT_SUCCESS);
}
void fortran_printf(double num)
{
int num_e = 0;
while (num > 1.0) {
num /= 10;
num_e++;
}
printf("%.5fE+%02d", num, num_e);
}
#包括
#包括
void fortran_printf();
内部主(空)
{
双数=274.600;
fortran_printf(num);
退出(退出成功);
}
void fortran_printf(双数值)
{
int num_e=0;
而(数值>1.0){
num/=10;
num_e++;
}
printf(“%.5fE+%02d”,num,num_e);
}
否则,您必须绕行字符串。请注意,上面的代码只是为了让您开始。它当然不会处理任何涉及的案例。字符串操作方法:
int printf_NoIntegerPart(double x, int prec) {
char buf[20 + prec];
sprintf(buf, "%+.*E", prec - 1, x * 10.0); // use + for consistent width output
if (buf[2] == '.') {
buf[2] = buf[1];
buf[1] = '.';
}
puts(buf);
}
int main(void) {
printf_NoIntegerPart(2.74600E+02, 5); // --> +.27460E+03
}
这将为DBL|u MAX/10打印“INF”printf()
无法使用某些特殊格式一步完成OP的目标。使用sprintf()
来形成初始文本结果是很好的第一步,在尝试使用字符串操作进行“数学”运算时必须小心
类似于删除的答案
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
int printf_NoIntegerPart(double x, int prec) {
assert(prec >= 2 && prec <= 100);
char buffer[prec + 16]; // Form a large enough buffer.
sprintf(buffer, "%.*E", prec - 1, x);
int dp = '.'; // Could expand code here to get current local's decimal point.
char *dp_ptr = strchr(buffer, dp);
char *E_ptr = strchr(buffer, 'E');
// Insure we are not dealing with infinity, Nan, just the expected format.
if (dp_ptr && dp_ptr > buffer && E_ptr) {
// Swap dp and leading digit
dp_ptr[0] = dp_ptr[-1];
dp_ptr[-1] = dp;
// If x was not zero …
if (x != 0) {
int expo = atoi(&E_ptr[1]); // Could use `strtol()`
sprintf(&E_ptr[1], "%+.02d", expo + 1);
}
}
return puts(buffer);
}
int main(void) {
printf_NoIntegerPart(2.74600E+02, 5); // ".27460E+03"
return 0;
}
#包括
#包括
#包括
int printf_NoIntegerPart(双x,int prec){
assert(prec>=2&&prec在fortran移植时面临同样的问题。
未找到标准C格式:(
使用log10/pow和字符串操作实现了这两种方法
#include <ansi_c.h>
#define BUFFL 16
// using log10 , 3 digits after "."
char* fformat1(char* b, double a) {
int sign = 1;
double mant;
double order;
int ord_p1;
if (a<0) {
sign =-1;
a = -a;
}
order=log10 (a);
if (order >=0) ord_p1 = (int) order +1; // due sto property of int
else ord_p1 = (int) order;
mant=a/(pow(10,ord_p1));
sprintf(b,"%.3fE%+03d",mant,ord_p1);
if (sign==-1) b[0]='-';
return b;
}
// using string manipulation
char* fformat2(char* b, double a) {;
int sign = 1;
int i;
int N=3;
if (a<0) {
sign =-1;
a = -a;
}
sprintf(b,"%0.3E",a*10); // remember - we *10 to have right exponent
b[1]=b[0]; // 3.123 => .3123
b[0]='.';
for (i=N; i>=0; i--) // and shif all left
b[i+1]=b[i];
b[0]='0'; // pad with zero 0.312
if (sign==-1) b[0]='-'; // sign if needed
return b;
}
int main () {
char b1[BUFFL]; // allocate buffer outside.
char b2[BUFFL];
char b3[BUFFL];
char b4[BUFFL];
char b5[BUFFL];
printf("%s %s %s %s %s \n", fformat(b1,3.1), fformat(b2,-3.0), fformat(b3,3300.),
fformat(b4,0.03), fformat(b5,-0.000221));
printf("%s %s %s %s %s \n", fformat2(b1,3.1), fformat2(b2,-3.0), fformat2(b3,3300.),
fformat2(b4,0.03), fformat2(b5,-0.000221));
return 1;
}
#包括
#定义BUFFL 16
//使用log10,在“.”之后加上3位数字
字符*fformat1(字符*b,双a){
int符号=1;
双螳螂;
双阶;
int ord_p1;
如果(a=0)ord_p1=(int)order+1;//由于int的sto属性
else ord_p1=(int)顺序;
mant=a/(功率(10,ord_p1));
sprintf(b,“%.3fE%+03d”,曼特,ord_p1);
如果(符号==-1)b[0]='-';
返回b;
}
//使用字符串操作
char*fformat2(char*b,双a){;
int符号=1;
int i;
int N=3;
如果(a.3123)
b[0]=';
for(i=N;i>=0;i--)//和shif全部左移
b[i+1]=b[i];
b[0]=“0”;//用0 0.312填充
if(sign==-1)b[0]='-';//需要时签名
返回b;
}
int main(){
char b1[BUFFL];//在外部分配缓冲区。
字符b2[BUFFL];
半焦b3[BUFFL];
炭b4[BUFFL];
炭b5[BUFFL];
printf(“%s%s%s%s%s\n”)、fformat(b1,3.1)、fformat(b2,-3.0)、fformat(B33300.),
fformat(b4,0.03),fformat(b5,-0.000221));
printf(“%s%s%s%s%s\n”)、fformat2(b1,3.1)、fformat2(b2,-3.0)、fformat2(B33300.),
fforma2(b4,0.03),fforma2(b5,-0.000221));
返回1;
}
我需要将它输入到一个旧的fortran可执行文件中。文本操作似乎是一种方法。你可以搜索一个库,但我猜没有人支持这种奇怪的格式。@avances123我认为应该将fortran信息添加到问题中。也许可以代替奇怪的“怪异”。@avances123:我也不知道。。你已经说过了;)