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?
lroundf bug
Re: lroundf bug
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.
lroundf(0.9f) and it returns 1 as it should. In my experience relying on implicit conversions is a bad idea.
Re: lroundf bug
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
Post your actual test code.
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);
Re: lroundf bug
Entire main.c
output from stdio
same code with same result on a MOD5234
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);
}
}
this was done on a MOD5270B using standard system libraries, NNDK 2.6.4Waiting 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
same code with same result on a MOD5234
Re: lroundf bug
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 referenceand then added this code down in main
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
Code: Select all
void do_nothing (float& myfloat)
{
cout << "No call to the rounding funcs "<< myfloat;
}
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";
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
Chiming in to say that we are now aware of the issue. We will try keep you apprised of the situation.
Dan Ciliske
Project Engineer
Netburner, Inc
Project Engineer
Netburner, Inc
Re: lroundf bug
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
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.