Page 1 of 1

[ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 16:55
by totorigolo
Salut à tous,

J'essaie en ce moment même de programmer un petit truc pour Nspire, et je me suis rendu compte que l'affichage des floats avec printf marche vraiment mal.

J'ai fait un code minimal que voici :
Code: Select all
#include <os.h>

int main()
{
    float timeStep = 1.f / 60.f;
    printf("Timestep = %5.4f\n", timeStep);

    float time;
    for (time = 0.f; time < 2.f; time += timeStep)
    {
        printf("Time is (%d) %5.4f\n", (int) time * 8.f, time);
    }

    return 0;
}


Et la sortie est très exotique...
Show/Hide spoilerAfficher/Masquer le spoiler
Timestep = 0.0000
Time is 0.0000
Time is 0.0000
Time is 0.0000
Time is -2.0000
Time is 0.0000
Time is 268156222240899000000000000000000000000000000000000000000000000000000000
000000
Time is -0.0000
Time is -26815622227419760000000000000000000000000000000000000000000000000000000
0000000
Time is 0.0000
Time is 2.0000
Time is 268156222303333800000000000000000000000000000000000000000000000000000000
000000
Time is -0.0000
Time is -0.0000
Time is -2.0000
Time is -26815622233663250000000000000000000000000000000000000000000000000000000
0000000
Time is 0.0000
Time is 0.0000
Time is 2.0000
Time is 268156222357444200000000000000000000000000000000000000000000000000000000
000000
Time is -0.0000
Time is -0.0000
Time is -2.0000
Time is -26815622237409360000000000000000000000000000000000000000000000000000000
0000000
Time is 0.0000
Time is 0.0000
Time is 2.0000
Time is 268156222390742900000000000000000000000000000000000000000000000000000000
000000
Time is -0.0000
Time is -0.0000
Time is -2.0000
Time is 268156222407392200000000000000000000000000000000000000000000000000000000
000000
Time is -26815622240947340000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222411554600000000000000000000000000000000000000000000000000000000
000000
Time is -26815622241363570000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222415716800000000000000000000000000000000000000000000000000000000
000000
Time is -26815622241779800000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222419879300000000000000000000000000000000000000000000000000000000
000000
Time is -26815622242196040000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222424041600000000000000000000000000000000000000000000000000000000
000000
Time is -26815622242612270000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222428203900000000000000000000000000000000000000000000000000000000
000000
Time is -26815622243028500000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222432366200000000000000000000000000000000000000000000000000000000
000000
Time is -26815622243444730000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222436528500000000000000000000000000000000000000000000000000000000
000000
Time is -26815622243860960000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222440690900000000000000000000000000000000000000000000000000000000
000000
Time is -26815622244277200000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222444853200000000000000000000000000000000000000000000000000000000
000000
Time is -26815622244693440000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222449015500000000000000000000000000000000000000000000000000000000
000000
Time is -26815622245109670000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222453177900000000000000000000000000000000000000000000000000000000
000000
Time is -26815622245525900000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222457340200000000000000000000000000000000000000000000000000000000
000000
Time is -26815622245942130000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222461502400000000000000000000000000000000000000000000000000000000
000000
Time is -26815622246358360000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222465664800000000000000000000000000000000000000000000000000000000
000000
Time is -26815622246774600000000000000000000000000000000000000000000000000000000
0000000
Time is 268156222469827200000000000000000000000000000000000000000000000000000000
000000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000
Time is 0.0000
Time is 2.0000
Time is -0.0000
Time is -2.0000


Néanmoins, il me semble que seul l'affichage s'excite, le reste fonctionne très bien (dans mon code complet).

Je ne sais pas si il s'agit d'une limitation de ndless ou d'une erreur de ma part. Je précise que la sortie est la même en compilant sous Windows et Linux.
Mon Makefile est le suivant :
Show/Hide spoilerAfficher/Masquer le spoiler
Code: Select all
GCCFLAGS = -O3
LDFLAGS = -L
GCC = nspire-gcc
LD = nspire-ld
OBJCOPY := "$(shell (which arm-elf-objcopy arm-none-eabi-objcopy arm-linux-gnueabi-objcopy | head -1) 2>/dev/null)"
ifeq (${OBJCOPY},"")
   OBJCOPY := arm-none-eabi-objcopy
endif
OBJS = main.o
DISTDIR = bin/
vpath %.tns $(DISTDIR)

all: test.tns

%.o: %.c
   $(GCC) $(GCCFLAGS) -c $<

%.o: %.S
   $(GCC) $(GCCFLAGS) -c $<

test.tns: $(OBJS)
   $(LD) $(LDFLAGS) $^ -o $(@:.tns=.elf)
   @mkdir -p $(DISTDIR)
   $(OBJCOPY) -O binary $(@:.tns=.elf) $(DISTDIR)/$@

clean:
   rm -f *.o *.elf
   rm -f $(DISTDIR)/test.tns

call: clean all


Si vous avez des infos, je suis donc preneur :)

totorigolo

Re: [ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 17:25
by Levak
Remplace
Code: Select all
(int) time * 8.f

Par
Code: Select all
(int)( time * 8.f)

D'ailleurs, dans ton printf, tu as une paire de parenthèses autour de %d que je ne vois pas dans ta sortie.. ?

Re: [ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 17:52
by totorigolo
Levak wrote:D'ailleurs, dans ton printf, tu as une paire de parenthèses autour de %d que je ne vois pas dans ta sortie.. ?


Normal, j'ai modifié le code et remplacé la sortie dans le post en oubliant de changer le code. C'était juste un test : sans le * 8f, ça donne 0 puis 1 (normal), avec ça sort des trucs chelous.
Code: Select all
printf("Time is %5.4f\n", time);

Re: [ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 19:31
by Lepzulnag
J'ai déjà expérimenté ces problèmes, et n'avait trouvé malheureusement aucune solution. Soit le %f est mal supporté par printf et sprintf, soit ce sont les flottants eux-même qui ne sont pas supportés.

Re: [ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 19:51
by totorigolo
J'en ai conclu que c'est le %f qui est mal supporté, parce que quand on s'en sert pour des opérations et qu'on utilise le résultat, il est bon.

Re: [ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 19:52
by Levak
Ça me fait penser à un hack que bsl a fait pour pouvoir gérer les doubles avec scanf : il fallait lire en little endian les deux octets (donc les inverser) car yagorto et le compilateur de TI ne suivent pas la même écriture en mémoire... peut-être chercher à faire un byte swap avant d'afficher ?

Re: [ndless] printf et nombres flottants

Unread postPosted: 22 Apr 2013, 19:53
by Excale
Yagarto :).
(ou Yaourt pour les intimes)

Re: [ndless] printf et nombres flottants

Unread postPosted: 23 Apr 2013, 12:31
by Lepzulnag
Levak wrote:Ça me fait penser à un hack que bsl a fait pour pouvoir gérer les doubles avec scanf : il fallait lire en little endian les deux octets (donc les inverser) car yagorto et le compilateur de TI ne suivent pas la même écriture en mémoire... peut-être chercher à faire un byte swap avant d'afficher ?


Qu'est-ce que tu entends par les deux octets ? Les deux premiers octets ?

J'ai tenté de lire à l'envers les 4 octets d'un flottant ou les 8 octets d'un double mais cela affiche tout de même des résultats incohérents.