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.