gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > sscanf() and float weirdness?

#160521 - ragefury32 - Thu Jul 17, 2008 5:59 am

Hm. So I ran into a weird problem with sccanf() -

So I have a block of code that look something like this:

Code:

  while((recv(my_socket, p, 1, 0) != 0) || i < 2000) {

  if (*p == '\n') {
    *p = '\0';
    char *area = linebuf;
    char *rest = strchr(linebuf, '|');
        *rest = '\0';
             p = linebuf;
            i = 0;

   char * cptr = NULL;
   char pipe[] = "|";   
   
   printf("%s\n", rest+1);
   
      cptr = strtok(rest+1, pipe);
      sscanf(cptr, "%4d", &tagid);
      iprintf("%4d, %f, %f, %f, %d\n", tagid, tx, ty, tz, flags);
       cptr = strtok( NULL, pipe);
      sscanf(cptr, "%f", &tx);
      iprintf("%4d, %f, %f, %f, %d\n", tagid, tx, ty, tz, flags);
       cptr = strtok( NULL, pipe);
      sscanf(cptr, "%f", &tz);
      iprintf("%4d, %f, %f, %f, %d\n", tagid, tx, ty, tz, flags);
      cptr = strtok( NULL, pipe);
      sscanf(cptr, "%f", &ty);   
      iprintf("%4d, %f, %f, %f, %d\n", tagid, tx, ty, tz, flags);
       cptr = strtok( NULL, pipe);
      sscanf(cptr, "%d\n", &flags);
      iprintf("%4d, %f, %f, %f, %d\n", tagid, tx, ty, tz, flags);
      break;
}


(Basically it goes to a non-blocking socket and pulls a string out of a server once every 5 seconds, a string that looks like:

recreation area|3.12332324|1.3234424|0|0

For some reason, the sscanf() always fail on the %f. What seems to be the problem? Is there something in terms of the sccanf that makes it bad?

#160528 - Maxxie - Thu Jul 17, 2008 8:43 am

Its the iprintf that fails the float, not the sscanf.

iprintf is a version of printf that has dropped float support to leave only int support.
_________________
Trying to bring more detail into understanding the wireless hardware

#160530 - a128 - Thu Jul 17, 2008 9:50 am

use ftoa() to convert float to a string
Code:

char *a=ftoa(whatever,2);
iprintf("%s",a);
free(a);


Last edited by a128 on Fri Jul 18, 2008 11:10 am; edited 1 time in total

#160536 - sgeos - Thu Jul 17, 2008 1:17 pm

a128 wrote:
use ftoa() to convert float to a string

Does iprintf paired with ftoa actually net you anything over vanilla printf? I assumed you either work with floats or you don't.

-Brendan

#160537 - a128 - Thu Jul 17, 2008 1:36 pm

sgeos wrote:

Does iprintf paired with ftoa actually net you anything over vanilla printf? I assumed you either work with floats or you don't.
-Brendan

Oh yes....use
Code:
printf("%0.2f",foo)

this works with floats....forget ftoa(foo,2)

#160566 - sgeos - Thu Jul 17, 2008 8:51 pm

a128 wrote:
sgeos wrote:

Does iprintf paired with ftoa actually net you anything over vanilla printf? I assumed you either work with floats or you don't.
-Brendan

Oh yes....use

What do you gain? Speed? ROM size? Both? iprintf paired with ftoa is certainly less readable.

-Brendan

#160598 - a128 - Fri Jul 18, 2008 8:08 am

sgeos wrote:

What do you gain? Speed? ROM size? Both? iprintf paired with ftoa is certainly less readable.
-Brendan

I just not tested printf with floats so I used ftoa() with iprintf.

#160603 - sgeos - Fri Jul 18, 2008 10:01 am

a128 wrote:
sgeos wrote:

What do you gain? Speed? ROM size? Both? iprintf paired with ftoa is certainly less readable.
-Brendan

I just not tested printf with floats so I used ftoa() with iprintf.

Without testing, how are you sure you net anything by using iprintf+ftoa instead of vanilla printf?

-Brendan

#160609 - a128 - Fri Jul 18, 2008 11:08 am

Quote:
Without testing, how are you sure you net anything by using iprintf+ftoa instead of vanilla printf?

What do you mean?

#160612 - sgeos - Fri Jul 18, 2008 11:44 am

a128 wrote:
Quote:
Without testing, how are you sure you net anything by using iprintf+ftoa instead of vanilla printf?

What do you mean?

So far as I can tell, ftoa is not part of the standard library. Are you sure it is not implemented with a vanilla sprintf? If it is, all you are doing is obfuscating your code by not using sprintf directly.

-Brendan

#160616 - silent_code - Fri Jul 18, 2008 2:05 pm

@ sgeos: Telling from his previous posts, I think he simply didn't know it worked, that's why he didn't use it. He even posted not to use his method, but to use printf directly with floats. ;^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#160908 - ragefury32 - Thu Jul 24, 2008 1:02 pm

silent_code wrote:
@ sgeos: Telling from his previous posts, I think he simply didn't know it worked, that's why he didn't use it. He even posted not to use his method, but to use printf directly with floats. ;^)


See, that is the part that worries me. I am not even sure if sscanf() is working properly, since when I tried to printf() the results, it either prints up blank, or when I push the results into the GL core, it seems to crash it. Also note that I split the string up on | and parse each individually instead of doing a simple tokenize on first, sscanf(&%d&%f|&%f|&%f|&%d, tagid, tx, ty, tz, flags) on the rest. I was having issue with both. How "big" is a float in the NDS? 32 Bit standard IEEE754 1-8-23, or something smaller?

Also, I cannot figure out whether the non-blocking recv() is working either. recv() seems to be sitting for a while before it returns anything.

#160914 - sgeos - Thu Jul 24, 2008 1:59 pm

Try sprintf-ing to sram, or some place in memory you can watch. That way you can inspect the results and see if the sprintf is working properly.

-Brendan

EDIT: You can use something like this. Plug a pointer to some known memory location into it. Definitely a hack, but if things are crashing...
Code:
void sprintfTest(char *buffer)
{
  float f = 12.34;
  int   i = 56;

  sprintf(buffer, "  f = %f;\n  i = %d;\n", f, i);
}


This is the PC-side output I get.
Code:
  f = 12.340000;
  i = 56;

#160919 - elhobbs - Thu Jul 24, 2008 3:14 pm

I was never able to get printf working with floats. It would always crash. The little bit of debugging I did before giving up pointed into locale related code - localeconv if I remember correctly. Since so many other people where having similiar issues I never tried too hard to get it to work. I was able to get sprintf to print floats to a string though (I think there may be issues if you do not have enough free ram though). I would just read the values in as strings and then convert them with atof.

#160923 - sgeos - Thu Jul 24, 2008 4:25 pm

elhobbs wrote:
I was able to get sprintf to print floats to a string though
What else is sprintf used for?

elhobbs wrote:
(I think there may be issues if you do not have enough free ram though).
Perhaps snprinf would solve this problem?

elhobbs wrote:
I would just read the values in as strings and then convert them with atof.
Unless you are working with user input, why not pass floats directly?

-Brendan

#160932 - elhobbs - Thu Jul 24, 2008 5:28 pm

sprintf is used to print to a character buffer instead of to the console.

no, I was not overflowing the buffer. I think internally the function tries to call malloc under certain situations and since I had intentionally grabbed nearly all of the ram it would fail.

I was trying to print debug strings for float values.

In any case I was just trying to point out that I have had similiar problems with floats. and that the quickest/best resolution may be to try an alternate approach since this appears to be a common issue.

#161155 - ragefury32 - Tue Jul 29, 2008 3:01 pm

So in other words, reading floats from an outside source (sccanf() off sockets) using this method is a bad idea then? What would be a realistic workaround to this? I mean, I can't avoid using it.

How would you use snscanf() in the case of a float?

snscanf(cptr, 6, "%f", &tz) or something like that?

#161181 - silent_code - Tue Jul 29, 2008 8:42 pm

You can always send bytes and all, you know. ;^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#161205 - elhobbs - Wed Jul 30, 2008 2:30 pm

you may have to manually parse the information instead of using scanf. can you confirm that you are even receiving the correct data?

here is one way to do it:
create a buffer to hold the longest possible line
move a full line into the buffer
use strtok to find the delimiters
then use atof on each piece to get the float value

#161343 - tepples - Fri Aug 01, 2008 8:23 pm

elhobbs wrote:
create a buffer to hold the longest possible line

How long is the longest possible line, and what do you want the program to do should the input exceed that?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#163603 - a128 - Mon Oct 06, 2008 9:59 am

using > devkitARMR21

i..e devkitARM R23 and this
Code:
 if ( sscanf ( s, "%f,%f,%f", &x, &y,&z ) != 3 ) {


does not work

using devkitARMR21 works!

#163607 - elhobbs - Mon Oct 06, 2008 2:02 pm

I found that a lot of the scanf/printf float problems that I was experiencing were caused by not having enough free memory or stack space. I eliminated all calls from recursive functions and I made sure that I left some memory free for the system functions (I think I left 128k free). My program uses it own memory heap so I was grabbing all of the memory from the system. Things stopped working when I went to r23 - leaving a little more free memory solved my issues.

#163610 - Izhido - Mon Oct 06, 2008 3:37 pm

a128 wrote:
using > devkitARMR21

i..e devkitARM R23 and this
Code:
 if ( sscanf ( s, "%f,%f,%f", &x, &y,&z ) != 3 ) {


does not work

using devkitARMR21 works!



Uh... pardon my eavesdropping, but... what exactly is that line supposed to do?

- Izhido

#163611 - kusma - Mon Oct 06, 2008 3:52 pm

Izhido wrote:
Uh... pardon my eavesdropping, but... what exactly is that line supposed to do?

Parse a string of three comma-separated floating point numbers.

#163617 - a128 - Mon Oct 06, 2008 5:13 pm

elhobbs wrote:
I found that a lot of the scanf/printf float problems that I was experiencing were caused by not having enough free memory or stack space. I eliminated all calls from recursive functions and I made sure that I left some memory free for the system functions (I think I left 128k free). My program uses it own memory heap so I was grabbing all of the memory from the system. Things stopped working when I went to r23 - leaving a little more free memory solved my issues.


No..it must be somethink else then memory....F&%$&$%&$ I had bugs in the core