From c36e8afd620dfbf554759e32dba1f4ac8cc7e134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Fri, 5 Oct 2018 22:56:58 +0200 Subject: [PATCH] feat: gestion des exposant et notation scientifique dans printf arg %e et %f --- include/video.h | 4 +- lib/video.c | 163 ++++++++++++++++++++++++++++++++++++------------ system/system.c | 5 +- 3 files changed, 126 insertions(+), 46 deletions(-) diff --git a/include/video.h b/include/video.h index dbde184..34e79a2 100755 --- a/include/video.h +++ b/include/video.h @@ -20,5 +20,5 @@ u32 printf (const u8 *string, ...); void changevc(u8 vc); u8* itoa(u64 num, u8* str, u8 base, u64 dim, u8 achar); u8* sitoa(u64 num, u8 * str, u64 dim); -u8* rtoadouble(double num, u8 * str, u8 precision); -u8* rtoasingle(float num, u8 * str, u8 precision); +u8* rtoadouble(double num, u8 * str, u8 precisioni , u8 precisionf); +u8* rtoasingle(float num, u8 * str, u8 precisioni , u8 precisionf); diff --git a/lib/video.c b/lib/video.c index 10aa913..230da08 100755 --- a/lib/video.c +++ b/lib/video.c @@ -313,13 +313,13 @@ u32 printf(const u8 * string, ...) u8 strbase16[] = "0x\000"; u8 hexadecimal[] = "*0x\000"; u8 achar, temp; - u8 asize, charadd, unit; + u8 asize, charadd, unit, precisioni, precisionf; u8 buffer[buffersize]; u8 *str = string; u8 *strtemp; u32 i = 0, counter = 0; u64 num; - bool flag = false; + bool flag = false, intok = false, decok = false; va_start(args, string); for (achar = *str; achar != '\000'; i++, achar = *(str + i)) { @@ -327,18 +327,22 @@ u32 printf(const u8 * string, ...) putchar(achar); counter++; asize = 2; + precisioni = 0; + precisionf = 0; + intok = false; + decok = false; charadd = 0xFF; } else if (achar == '%' || flag) { if (!flag) ++i; achar = *(str + i); switch (achar) { - case '0': - charadd = '0'; + case 'z': + charadd = achar; flag = true; break; case ' ': - charadd = ' '; + charadd = achar; flag = true; break; case 'h': @@ -351,28 +355,54 @@ u32 printf(const u8 * string, ...) if (asize>3) asize=3; flag = true; break; + case '.': + intok=true; + decok=false; + flag = true; + break; + case '0': case '1': case '2': case '3': - asize=0; - flag = true; - break; case '4': case '5': case '6': case '7': - asize=1; - flag = true; - break; case '8': - asize=2; - flag = true; - break; case '9': - asize=3; - flag = true; + if (!intok) + { + if (!decok) + { + precisioni=achar-'0'; + decok=true; + } + else { + precisioni*=10; + precisioni+=achar-'0'; + decok=false; + } + } + else { + if (!decok) + { + precisionf=achar-'0'; + decok=true; + } + else { + precisionf*=10; + precisionf+=achar-'0'; + decok=false; + } + } + flag = true; break; case 'f': + case 'e': + if (achar=='e') { + precisioni=1; + precisionf=8; + } if (asize==0) { num = (u64) va_arg(args, u8); break; @@ -382,9 +412,9 @@ u32 printf(const u8 * string, ...) break; } else if (asize==2) - rtoasingle((float)va_arg(args, double), &buffer, 5); + rtoasingle((float)va_arg(args, double), &buffer, precisioni, precisionf); else - rtoadouble((double)va_arg(args, double), &buffer, 5); + rtoadouble((double)va_arg(args, double), &buffer, precisioni, precisionf); counter += print(&buffer); flag = false; break; @@ -525,34 +555,85 @@ u32 printf(const u8 * string, ...) /*******************************************************************************/ /* converti un réel signé en chaine de caractère */ -u8 *rtoadouble(double num, u8 * str, u8 precision) { - u8 *pointer=str; - u32 integerpart = (int)num; - double fracpart = num - (double)integerpart; - pointer = sitoa(integerpart, str, 0xFFFFFFFF); - if (precision != 0) - { - *pointer = '.'; - fracpart = fracpart * pow(10, precision); - sitoa((u32)fracpart, pointer+1, 0xFFFFFFFF); - } +u8 *rtoadouble(double num, u8 * str, u8 precisioni , u8 precisionf) { + s8 power10; + u8 *pointer=str; + u8 i,j,integerpart,fracpart; + if (precisioni==0) precisioni=12; + if (precisionf==0) precisionf=8; + bool intok=false; + if (num<0) { + num=-num; + *(pointer++) = '-'; + } + power10=0; + { + while (num>=10.0) { + num/=10; + power10++; + } + } + if (power100) + { + if (!intok & (i>fracpart || i>=precisioni)) { + *(pointer++) = '.'; + intok=true; + } + if (intok && j>=precisionf) + break; + num-= (integerpart=num); + *(pointer++) = integerpart+'0'; + num*=10.0; + if (!intok) + i++; + else + j++; + } + while((*(pointer-1))=='0' && pointer>str+1) + pointer--; + if ((*(pointer-1))=='.') pointer--; + if (abs(power10)>0) + { + *(pointer++) = 'e'; + if (power10<0) { + power10=-power10; + *(pointer++) = '-'; + } + *(pointer++) = (power10/10+'0'); + *(pointer++) = (power10%10+'0'); + } + *(pointer++) = 0; } /*******************************************************************************/ /* converti un réel signé en chaine de caractère */ -u8 *rtoasingle(float num, u8 * str, u8 precision) { - u8 *pointer=str; - u32 integerpart = (int)num; - float fracpart = num - (float)integerpart; - pointer = sitoa(integerpart, str, 0xFFFFFFFF); - if (precision != 0) - { - *pointer = '.'; - fracpart = fracpart * pow(10, precision); - itoa((u32)fracpart, pointer+1, 10 , precision, '0'); - } - return pointer; + +u8 *rtoasingle(float num, u8 * str, u8 precisioni , u8 precisionf) { + return rtoadouble((double)num, str, precisioni, precisionf); } /*******************************************************************************/ diff --git a/system/system.c b/system/system.c index b63ed2c..52b4871 100755 --- a/system/system.c +++ b/system/system.c @@ -107,9 +107,8 @@ int main(u32 magic, u32 addr) initsyscall(); ok(); - float test=3.14f; - double test2=3.14; - printf(" -Test float & double %f %lf %f %f %f %f",test,test2,0.1212412544f,0.1f,15545485425425425425425425425427878787.0f,0.0001f); + float test=-12101412121212121212.5555555555555555f; + printf(" -Test float & double :\r\n %e \r\n %f\r\n %1.2f\r\n %.2f\r\n %4.1f\r\n %10.5f\r\n %6f\r\n %8f",test,test,test,test,test,test,test,test); retry: shell(); }