MOD5234 - problem with float-to-string routines

Discussion to talk about software related topics only.
pbersch
Posts: 4
Joined: Fri Apr 26, 2013 5:56 am

MOD5234 - problem with float-to-string routines

Post by pbersch »

Hello!
I have a strange effect when using standard routines to output a float value: if the value is in the range -1< fValue < 1, the leading "0" shows as "2" (or as "7", in another project). Example:

float fValue = 0.1;
printf("Value = %5.3f \n", fValue);

would produce the output:
Value = 2.100

It's the same with sprintf or other functions which convert a float value to string characters; integer-Outputs (i.e. iprintf("iValue = %d \n", 0); ) work fine.
The Problem doesn't exist in Debug mode.
I'm quite sure I got correct outputs with an earlier version of Netburner IDE, but I don't know since which version I encountered the problem.

Did anyone see something like that, too? Any suggestions how to solve the problem?

Thanks for your help,

Patricia
seulater
Posts: 445
Joined: Fri Apr 25, 2008 5:26 am

Re: MOD5234 - problem with float-to-string routines

Post by seulater »

I know this may not help all to much as i dont have a MOD5234 laying around, But i did try it on a Nano and the result was "Value = 0.100"
ecasey
Posts: 164
Joined: Sat Mar 26, 2011 9:34 pm

Re: MOD5234 - problem with float-to-string routines

Post by ecasey »

Try making "float fValue" volitile. It could be that the optimizer is stepping in and not re-calculating the expression.
If that works, then it might be that another variable is overwriting part of the fValue memory space.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: MOD5234 - problem with float-to-string routines

Post by tod »

Code: Select all

float fValue = 0.1;
is the equivalent of writing

Code: Select all

double temp = 0.1;
float fvalue = static_cast<float>(temp);
You can avoid the implicit conversion by using the correct literal syntax for assigning a float

Code: Select all

float fValue = 0.1f;
This would eliminate the possibllity that there is something wrong with the implicit casting. I doubt that's the case though. (I also wouldn't be too surprised if the compiler is smart enough to avoid the implicit cast but I always think its better to write what you mean, rather than rely on compiler optimizations). You could also try using C++'s <iostream> instead of the C<stdio> and see if the problem is there i.e.

Code: Select all

cout << fValue;
plus it gets you type safety (but using iostream does impose a memory hit on flash usage).

BUT, after all that, you should really create a program that does NOTHING but this test. I agree with ecasey, since no one else is reporting this, it seems most likely to me that you are corrupting memory somewhere else in your program. You could use https://gist.github.com/ to post some code if you think it would be complete enough for us spot a problem. Unfortunately, I don't have a MOD5234 to test on but again the odds of it being a hardware problem (it's not a Pentium after all) seem exceedingly teensy-tiny.
pbersch
Posts: 4
Joined: Fri Apr 26, 2013 5:56 am

Re: MOD5234 - problem with float-to-string routines

Post by pbersch »

Well, I created a new project which does nothing but the test output, which is o.k.; so I have to find out what's in my other projects, that corrupts the memory. Since no one else seems to have the problem, I assumed yet the problem is on the side of my program. But since it happened everywhere I tried a float-formatted output, it seems to be sort of general problem anyhow. Maybe your further advices will help me to narrow down the reason for this strange behaviour...
ecasey
Posts: 164
Joined: Sat Mar 26, 2011 9:34 pm

Re: MOD5234 - problem with float-to-string routines

Post by ecasey »

Did you try adding the "volatile" keyword to the "fValue" declaration in your original code?
That might give us a hint if it is the optimizer that is causing the difference between Debut and Run modes.

If you are using arrays, check to see that they are all long enough to ensure that all uses are within the bounds. In my experience, it is usually overrunning an array that causes this sort of problem.

When using "sprintf" and "iprintf" make sure that there are enough variables for the number of "%" arguments. Or, better yet, as Tod suggests, use streaming output which cannot be fooled.

Ed
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: MOD5234 - problem with float-to-string routines

Post by tod »

You would need to post some code on gist that replicates the problem for us to do more than guess. But I'll guess anyway. Are you using sprintf or any of the unsafe forms of memcpy strcpy etc? Those are the usual suspects, they make it quite easy to overwrite memory accidentally. The solution in my mind is to use the C++ stdlib instead of the C libs. However, there are at least safer counted forms of most C libs that should always be preferred, from strncpy, snprintf etc. I think the only safe version of memcpy is to not use it. Improper use of printf (and all its siblings) can also be quite dangerous, usually when you change the type of a variable but forget to change the format specifier in the printf.
pbersch
Posts: 4
Joined: Fri Apr 26, 2013 5:56 am

Re: MOD5234 - problem with float-to-string routines

Post by pbersch »

I tried some of your hints, for example:

volatile float fValue = 0.1;
float fValue 0.1f;
double fValue 0.1;

but to no avail.

I tried to include iostream to be able to use cout,
#include <iostream>
cout << fValue;

but 1 got a compiler error message:

In file included from c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/m68k-elf/m5208/bits/c++locale.h:48,
from c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/iosfwd:45,
from c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/ios:43,
from c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/ostream:45,
from c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/iostream:45,
from ..\main.cpp:19:
c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/cstring:88: error: '::strcoll' has not been declared
c:\nburn\gcc-m68k\bin\../lib/gcc/m68k-elf/4.2.1/../../../../m68k-elf/include/c++/4.2.1/cstring:90: error: '::strxfrm' has not been declared
..\main.cpp: In function 'void TestFunction()':
..\main.cpp:777: error: 'cout' was not declared in this scope


The used variable itself doesn't seem to be corrupted, but only the output string; to output fValue*10.0 (which is out of the critical range -1 < fValue < +1) produces correct output:

volatile float fValue = 0.1;
printf("Value = %5.3f \n", fValue);
printf("10*Value = %5.3f ", fValue*10.0);

produces the output:

Value = 7.100
10*Value = 1.000
ecasey
Posts: 164
Joined: Sat Mar 26, 2011 9:34 pm

Re: MOD5234 - problem with float-to-string routines

Post by ecasey »

Try
std::cout << fValue;

or

put "using namespace std" after "#include <iostream>"

cout is in the "std" namespace.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: MOD5234 - problem with float-to-string routines

Post by tod »

What version of the NNDK are you using? This is starting to sound familiar, although that problem was more repeatable. I also want to know what version of the GNU compiler you're using so dig down through this path
C:\nburn\gcc-m68k\m68k-elf\include\c++
and tell me if you see a folder named 4.2.1, if not what is it called?

I also just noticed you said it went away in debug mode. That points to optimization problems. You can narrow that down by changing your release build to use None -O0 (see the attached image if you're not familiar with doing this). If the problem goes away it's an optimization bug.
Attachments
Optimize.png
Optimize.png (115.83 KiB) Viewed 13885 times
Post Reply