Avatar billede Slettet bruger
02. februar 2009 - 13:00 Der er 6 kommentarer og
1 løsning

Float til String uden brug af sprintf

Hej

Hvordan kan jeg lettest og på mindst mulig plads konvetere en float til en string?

sprintf oog den slags fra stdio.h er ikke tillladt da den optager alt formeget plads.

/Peter
Avatar billede bertelbrander Novice
02. februar 2009 - 20:51 #1
Hvis sprintf optager for meget plads til at du kan udskrive floats, så lad være.

Du kan måske godt strikke noget sammen, der kan udskrive nogle floating point tal, der fylder mindre end sprintf, f.eks. hvis du ved at dine floats er i et bestemt range. Men du kan sandsynligvis ikke lave en funktion der fylder mindre end sprintf, hvis du skal kunne det samme.

Nogle C compilere til små embeddede/indlejrede systemer, lader dig bestemme hvilken version af sprintf du får, så du kan vælge en der ikke fylder så meget, men så heller ikke kan ret meget.

Hvilken platform er det til?
Avatar billede bertelbrander Novice
02. februar 2009 - 22:43 #2
Hvis du kan leve med at de største tal er 1000000 og at alle tal udskrives med to cifre efter comma, kan du bruge:

#include <stdio.h>
void PutFloat(float f)
{
  int i, flag = 0, n;
  float j = 1000000;
  for(i = 0; i < 7; i++)
  {
      n = int(f/j);
      n %= 10;
      j /= 10;
      if(n)
      {
        flag = 1;
        putc(n + '0', stdout);
      }
      else if(flag)
        putc('0', stdout);
  }
  putc('.', stdout);
  n = int(f*10)%10;
  putc(n + '0', stdout);
  n = int(f*100)%10;
  putc(n + '0', stdout);
}

int main()
{
  PutFloat(123);
  putc('\n', stdout);
  PutFloat(1234567);
  putc('\n', stdout);
  PutFloat(1234567.89);
  putc('\n', stdout);
}
Avatar billede arne_v Ekspert
03. februar 2009 - 01:55 #3
Mit forslag:

#include <stdio.h>

static int pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

void i2s(int v, int w, char *buf, char fill)
{
    int i,tmp;
    char *p = buf + w;
    *p = '\0';
    p--;
    tmp = v;
    for(i = 0; i < w; i++)
    {
        if(tmp > 0)
        {
            *p = '0' + tmp % 10;
            tmp /= 10;
        }
        else
        {
            *p = fill;
        }
        p--;
    }
}

void f2s(float x, int w, int nd, char *buf)
{
    int tmp;
    tmp = (int)x;
    i2s(tmp, w - nd - 1, buf, ' ');
    buf[w - nd - 1] = '.';
    i2s((int)((x - tmp) * pow10[nd]), nd, buf + w - nd, '0');
}

#define MAX(a,b) (a>b?a:b)

void f2s_free(float x, char *buf)
{
    int n = 1;
    while(x >= pow10[n]) n++;
    f2s(x, MAX(8,n+2), MAX(1,7-n), buf);
}

int main()
{
    char buf[16];
    float x = 123.456;
    printf("%9.4f\n", x);
    f2s(x, 9, 4, buf);
    printf("%s\n", buf);
    printf("%f\n", x);
    f2s_free(x, buf);
    printf("%s\n", buf);
    return 0;
}

Max. 9 tegn foer punktum og max. 9 tegn efter punktum.
Avatar billede arne_v Ekspert
03. februar 2009 - 03:55 #4
Der er to grunde til at brug af en custom funktion kan fylde mindre end brug af standard printf:
* mindre funktionalitet i funktionen => mindre kode
* man kan nøjes med de funktioner som man faktisk skal bruge og behøver ikke at loade et helt modul som indeholder både funktioner man skal bruge og funktioner som man ikke skal bruge ind
Avatar billede Slettet bruger
28. december 2009 - 20:22 #5
Laver I et svar :o)
Avatar billede bertelbrander Novice
28. december 2009 - 20:31 #6
Jeg samler ikke på point.
Avatar billede arne_v Ekspert
28. december 2009 - 20:36 #7
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester