📄 stdio.c
字号:
};
j=precision;
pad_left:
if ((flags & F_LEFT_JUSTIFY)==0)
while ((width>l) && (width>j))
{
if (flags & F_PAD_CHR0)
{
if (flags & F_SIGNED)
{
flags&=~F_SIGNED;
k=s;
--l;
}
else k='0';
}
else k=' ';
_put(k,ps_ptr,&max_size);
--width;
};
while (precision>l)
{
flags|=F_NON_ZERO;
if (flags & F_SIGNED)
{
_PRINT_SIGN();
--l;
--precision;
};
_put('0',ps_ptr,&max_size);
if (width) --width;
--precision;
};
j=l;
if (base==0)
{
while (j)
{
if (flags & F_STRING_FLASH) _put(*pp.pf++,ps_ptr,&max_size);
else _put(*pp.p++,ps_ptr,&max_size);
if (width) --width;
--j;
};
}
else
do
{
k=(unsigned char) (n/i);
if (k>9)
{
if (flags & F_CAPS) k+=0x37;
else k+=0x57;
}
else k+='0';
if (flags & F_NON_ZERO) goto print_digit;
if ((k>'0') || (i==1)) goto print_sign;
if (precision>=j)
{
k='0';
goto print_sign;
};
if ((width>=j) && ((flags & F_LEFT_JUSTIFY)==0))
{
k=' ';
if (flags & F_PAD_CHR0)
{
k='0';
print_sign:
flags|=F_NON_ZERO;
if (flags & F_SIGNED) _PRINT_SIGN();
};
print_digit:
_put(k,ps_ptr,&max_size);
if (width) --width;
};
--j;
n%=i;
i/=base;
}
while (i);
if (flags & F_LEFT_JUSTIFY)
while (width)
{
--width;
_put(' ',ps_ptr,&max_size);
};
default:
next:
l=TEST_FORMAT;
};
};
}
#elif defined _PRINTF_FLOAT_WIDTH_PRECISION_
#include <math.h>
#define F_LEFT_JUSTIFY 1
#define F_LONG 2
#define F_SIGNED 4
#define F_CAPS 8
#define F_STRING_FLASH 8
#define F_NON_ZERO 0x10
#define F_USE_PRECISION 0x20
#define F_PAD_CHR0 0x80 // pad char is '0'
union arg_u {
unsigned long n;
float nf;
};
static flash float _fround[7]={0.5,0.05,0.005,0.0005,0.00005,0.000005,0.0000005};
static void _ftoa(float n,unsigned char decimals,char *str)
{
float scale;
unsigned char i,d;
if (decimals>6) decimals=6;
n=n+_fround[decimals];
i=0;
scale=1.0;
while (n>=scale) {scale=scale*10.0; ++i;};
if (i==0) *str++='0';
else
while (i--)
{
scale=floor(0.5+scale/10.0);
d=(unsigned char) (n/scale);
*str++=d+'0';
n=n-scale*d;
};
if (decimals==0) {*str=0; return;};
*str++='.';
while (decimals--)
{
n=n*10.0;
d=(unsigned char) n;
*str++=d+'0';
n=n-d;
};
*str=0;
}
static void _ftoe(float n,unsigned char decimals,char e,char *str)
{
float scale;
unsigned char i,d;
signed char expon;
scale=1.0;
if (decimals>6) decimals=6;
i=decimals;
while (i--) scale=scale*10.0;
if (n==0.0) {expon=0; scale=scale*10.0;}
else
{
expon=decimals;
if (n>scale)
{
scale=scale*10.;
while (n>=scale) {n=n/10.0; ++expon;};
}
else
{
while (n<scale) {n=n*10.0; --expon;};
scale=scale*10.0;
};
n+=0.5;
if (n>=scale) {n=n/10.0; ++expon;};
}
i=0;
while (i<=decimals)
{
scale=floor(0.5+scale/10.0);
d=(unsigned char) (n/scale);
*str++=d+'0';
n=n-(float) d*scale;
if (i++) continue;
*str++ ='.';
};
*str++=e;
if (expon<0) {*str++='-'; expon=-expon;};
if (expon>9) *str++='0'+expon/10;
*str++='0'+expon%10;
*str=0;
}
#define _PRINT_SIGN() {flags&=~F_SIGNED; _put(s,ps_ptr,&max_size); if (width) --width;}
#ifdef _MODEL_TINY_
static void _print(char flash *fmtstr,va_list argptr,ps_s *ps_ptr, unsigned char max_size)
#else
static void _print(char flash *fmtstr,va_list argptr,ps_s *ps_ptr, unsigned int max_size)
#endif
{
char pbuf[64];
unsigned char l=TEST_FORMAT,flags,j,k,width,precision,s,base;
#ifdef _MODEL_TINY_
unsigned char msize;
#else
unsigned int msize;
#endif
unsigned long i;
union ptr_u pp;
union arg_u arg_val;
msize=max_size;
while (k=*fmtstr++)
switch (l)
{
case TEST_FORMAT: if (k=='%') l=GET_FLAGS; else _put(k,ps_ptr,&msize);
break;
case GET_FLAGS: if (k=='%') {_put(k,ps_ptr,&msize); l=TEST_FORMAT; break;};
l=GET_PAD_CHAR;
s=0;
flags=0;
if (k=='-') {flags=F_LEFT_JUSTIFY; break;};
if (k=='+') {s='+'; break;};
if (k==' ') {s=' '; break;};
case GET_PAD_CHAR:
width=0;
l=GET_WIDTH;
if (k=='0') {flags|=F_PAD_CHR0; break;}
case GET_WIDTH:
if ((k>='0') && (k<('9'+1)))
{
#ifdef _ENHANCED_CORE_
width*=10;
#else
j=width;
width<<=2;
width+=j;
width<<=1;
#endif
width+=k-'0';
break;
};
precision=0;
if (k=='.') {l=GET_PRECISION; break;}
goto test_long;
case GET_PRECISION:
if ((k>='0') && (k<('9'+1)))
{
flags|=F_USE_PRECISION;
#ifdef _ENHANCED_CORE_
precision*=10;
#else
j=precision;
precision<<=2;
precision+=j;
precision<<=1;
#endif
precision+=k-'0';
break;
};
test_long:
if (k=='l')
{
flags|=F_LONG;
l=DO_PRINT;
break;
};
case DO_PRINT:
switch (k)
{
case 'c':
_put(va_arg(argptr,char),ps_ptr,&msize);
goto next;
case 'E':
case 'e':
case 'f':
pp.p=pbuf;
if ((arg_val.nf=*((float *) argptr--))>=0)
{
if (s=='+') goto disp_sign;
}
else
{
arg_val.nf=-arg_val.nf;
s='-';
disp_sign:
if (flags & F_PAD_CHR0) _put(s,ps_ptr,&msize);
else *pp.p++=s;
};
if ((flags & F_USE_PRECISION)==0) precision=6;
if (k=='f') _ftoa(arg_val.nf,precision,pp.p);
else _ftoe(arg_val.nf,precision,k,pp.p);
pp.p=pbuf;
l=strlen(pp.p);
goto disp_string1;
case 's':
pp.p=va_arg(argptr,char *);
l=strlen(pp.p);
goto disp_string0;
case 'p':
pp.pf=va_arg(argptr,char flash *);
l=strlenf(pp.pf);
flags|=F_STRING_FLASH;
disp_string0:
flags&=~F_PAD_CHR0;
if (precision && (l>precision))
l=precision;
disp_string1:
precision=0;
base=0;
j=0;
goto pad_left;
case 'd':
case 'i':
flags|=F_SIGNED;
case 'u':
base=10;
if (flags & F_LONG)
{i=1000000000L; l=10; goto get_arg;};
i=10000; l=5;
goto get_arg;
case 'X':
flags|=F_CAPS;
case 'x':
base=16;
if (flags & F_LONG)
{i=0x10000000L; l=8; goto get_arg;};
i=0x1000; l=4;
get_arg:
if (precision) flags&=~F_PAD_CHR0;
else precision=1;
if (flags & F_LONG) arg_val.n=va_arg(argptr,long);
else
if (flags & F_SIGNED) arg_val.n=va_arg(argptr,int);
else arg_val.n=va_arg(argptr,unsigned);
if (flags & F_SIGNED)
{
if ((long) arg_val.n<0)
{
arg_val.n=-(long) arg_val.n;
s='-';
};
if (s) {++l; ++precision;}
else flags&=~F_SIGNED;
};
j=precision;
pad_left:
if ((flags & F_LEFT_JUSTIFY)==0)
while ((width>l) && (width>j))
{
if (flags & F_PAD_CHR0)
{
if (flags & F_SIGNED)
{
flags&=~F_SIGNED;
k=s;
--l;
}
else k='0';
}
else k=' ';
_put(k,ps_ptr,&msize);
--width;
};
while (precision>l)
{
flags|=F_NON_ZERO;
if (flags & F_SIGNED)
{
_PRINT_SIGN();
--l;
--precision;
};
_put('0',ps_ptr,&msize);
if (width) --width;
--precision;
};
j=l;
if (base==0)
{
while (j)
{
if (flags & F_STRING_FLASH) _put(*pp.pf++,ps_ptr,&msize);
else _put(*pp.p++,ps_ptr,&msize);
if (width) --width;
--j;
};
}
else
do
{
k=(unsigned char) (arg_val.n/i);
if (k>9)
{
if (flags & F_CAPS) k+=0x37;
else k+=0x57;
}
else k+='0';
if (flags & F_NON_ZERO) goto print_digit;
if ((k>'0') || (i==1)) goto print_sign;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -