Page 1 of 1
lroundf bug
Posted: Sun May 04, 2014 10:58 pm
by roland.ames
I have found that lroundf() truncates instead of rounding
lroundf(0.1) = 0
lroundf(0.9) = 0
lround() works correctly
lround(0.1) = 0
lround(0.9) = 1
this seems to have been found before
see
http://cygwin.com/ml/cygwin/2007-08/msg00656.html
Is anyone aware of any other floating point library problems?
Re: lroundf bug
Posted: Mon May 05, 2014 11:13 am
by tod
lroundf takes a float and you're passing a double. I tested with
lroundf(0.9f) and it returns 1 as it should. In my experience relying on implicit conversions is a bad idea.
Re: lroundf bug
Posted: Mon May 05, 2014 11:34 am
by tod
Just ran another test with explicit and implicit casts from double and they too worked.
Testing NNDK 2.6.4 (which uses gcc 4.2.1) on a MOD5272
Code: Select all
cout << "\nround with implicit cast from 0.1 double " << lroundf(0.1);
cout << "\nround with implicit cast from 0.9 double " << lroundf(0.9);
cout << "\nround with explicit cast from double " << lroundf((float)0.9);
cout << "\nround with float "<<lroundf(0.9f);
Post your actual test code.
Re: lroundf bug
Posted: Mon May 05, 2014 6:39 pm
by roland.ames
Entire main.c
Code: Select all
#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <dhcpclient.h>
#include <smarttrap.h>
#include <taskmon.h>
#include <NetworkDebug.h>
#include <math.h>
extern "C" {
void UserMain(void * pd);
}
const char * AppName="test_MOD5270B";
void tst_fplib(float tv)
{
double dtv = (double)(tv);
printf("\nf=%f\n", dtv);
long int li = lroundf(tv);
printf("lroundf(f) = %ld\n", li);
li = lround(dtv);
printf("lround(f) = %ld\n\n", li);
}
void test_float_point_libs(void)
{
tst_fplib(0.9f);
tst_fplib(0.5f);
tst_fplib(0.1f);
tst_fplib(-0.9f);
tst_fplib(-0.5f);
tst_fplib(-0.1f);
}
void UserMain(void * pd) {
InitializeStack();
if (EthernetIP == 0) GetDHCPAddress();
OSChangePrio(MAIN_PRIO);
EnableAutoUpdate();
StartHTTP();
EnableTaskMonitor();
#ifndef _DEBUG
EnableSmartTraps();
#endif
#ifdef _DEBUG
InitializeNetworkGDB_and_Wait();
#endif
iprintf("Application started\n");
test_float_point_libs();
while (1) {
OSTimeDly(20);
}
}
output from stdio
Waiting 2sec to start 'A' to abort
Configured IP = 0.0.0.0
Configured Mask = 255.255.255.0
MAC Address= 00:03:f4:05:e1:3b
Application started
f=0.900000
lroundf(f) = 0
lround(f) = 1
f=0.500000
lroundf(f) = 0
lround(f) = 1
f=0.100000
lroundf(f) = 0
lround(f) = 0
f=-0.900000
lroundf(f) = 0
lround(f) = -1
f=-0.500000
lroundf(f) = 0
lround(f) = -1
f=-0.100000
lroundf(f) = 0
lround(f) = 0
this was done on a MOD5270B using standard system libraries, NNDK 2.6.4
same code with same result on a MOD5234
Re: lroundf bug
Posted: Tue May 06, 2014 12:06 pm
by tod
I recreated your code on a MOD5272 and I can replicate it. This is scary. The error seems to only happen when you pass the float (or double) as a parameter. This made me wonder if the value was getting changed or copied incorrectly when passed as a parameter. I wrote this function to pass the float as a reference
Code: Select all
void do_nothing (float& myfloat)
{
cout << "No call to the rounding funcs "<< myfloat;
}
and then added this code down in main
Code: Select all
float new_float = 0.9f;
cout << "\nBEFORE "<< new_float<< "result:" << lroundf(new_float) <<"\n";
do_nothing(new_float);
cout << "\nAFTER do_nothing() lroundf of "<< new_float<< "result:" << lroundf(new_float) <<"\n";
Before passing to do_nothing lroundf correctly returns 1. After the call to do nothing the call to lroundf incorrectly reports 0. Indicating to me that somehow new_float was changed by passing it to do_nothing(). At least it changed as far as lroundf was concerned.
The actual output was
BEFORE 0.9result:1
No call to the rounding funcs 0.9
AFTER do_nothing() lroundf of 0.9result:0
Re: lroundf bug
Posted: Tue May 06, 2014 12:38 pm
by dciliske
Chiming in to say that we are now aware of the issue. We will try keep you apprised of the situation.
Re: lroundf bug
Posted: Tue May 06, 2014 1:17 pm
by tod
Thanks Dan, it's always good to know you guys are listening. In case it helps I just created a simple desktop program using Eclipse and the Mingw toolchain (which is using gcc 4.7.2) and the problem does not occur so I suspect at some point a bug was found and fixed in the gcc libs. A good excuse to move to 4.7.2 or even 4.9.0? Of course as a side benefit that would get us C++11 compliance. Hidden motive? Who me?
Re: lroundf bug
Posted: Tue May 06, 2014 6:53 pm
by roland.ames
Thanks for confirming the problem Tod. I would have been very concerned if your result was different to mine! Hopefully NB can sort this out, meanwhile I am doing all my floating point calcs using double instead of float.