Bug 43350 - llroundl(x) fails for certain values of x
llroundl(x) fails for certain values of x
Status: CLOSED CURRENTRELEASE
Product: Red Hat Linux
Classification: Retired
Component: libc (Show other bugs)
7.1
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-06-03 12:44 EDT by Trevin Beattie
Modified: 2007-04-18 12:33 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-03-08 08:45:28 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Trevin Beattie 2001-06-03 12:44:16 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.2-2 i586)

Description of problem:
Apparently I discovered this bug by accident.  If the rounded value of x is
a power of 2 at least 2^32 large, llroundl() will return zero.


How reproducible:
Always

Steps to Reproduce:
Compile and run the following program:

#include <stdio.h>
#define __USE_ISOC99 1
#include <math.h>

main ()
{
  long long ll;
  int i, r = 0;
  static const long long test_cases[] = {
    2147483646LL, 2147483647LL, 2147483648LL,
    4294967294LL, 4294967295LL, 4294967296LL,
    6442450942LL, 6442450943LL, 6442450944LL,
    8589934590LL, 8589934591LL, 8589934592LL,
    12884901886LL, 12884901887LL, 12884901888LL,
    17179869182LL, 17179869183LL, 17179869184LL,
    25769803774LL, 25769803775LL, 25769803776LL,
    1099511627774LL, 1099511627775LL, 1099511627776LL,
    4503599627370494LL, 4503599627370495LL, 4503599627370496LL,
  };

  for (i = 0; i < sizeof (test_cases) / sizeof (long long); i++) {
    ll = llroundl (test_cases[i] + 0.5L);
    printf ("llroundl (%.1Lf) returns %lld\n",
	    test_cases[i] + 0.5L, ll);
    if (ll != ((test_cases[i] >= 0)
	       ? (test_cases[i] + 1LL) : test_cases[i]))
      r = 1;
  }
  return r;
}


Actual Results:  llroundl (2147483646.5) returns 2147483647
llroundl (2147483647.5) returns 2147483648
llroundl (2147483648.5) returns 2147483649
llroundl (4294967294.5) returns 4294967295
llroundl (4294967295.5) returns 0
llroundl (4294967296.5) returns 4294967297
llroundl (6442450942.5) returns 6442450943
llroundl (6442450943.5) returns 6442450944
llroundl (6442450944.5) returns 6442450945
llroundl (8589934590.5) returns 8589934591
llroundl (8589934591.5) returns 0
llroundl (8589934592.5) returns 8589934593
llroundl (12884901886.5) returns 12884901887
llroundl (12884901887.5) returns 12884901888
llroundl (12884901888.5) returns 12884901889
llroundl (17179869182.5) returns 17179869183
llroundl (17179869183.5) returns 0
llroundl (17179869184.5) returns 17179869185
llroundl (25769803774.5) returns 25769803775
llroundl (25769803775.5) returns 25769803776
llroundl (25769803776.5) returns 25769803777
llroundl (1099511627774.5) returns 1099511627775
llroundl (1099511627775.5) returns 0
llroundl (1099511627776.5) returns 1099511627777
llroundl (4503599627370494.5) returns 4503599627370495
llroundl (4503599627370495.5) returns 0
llroundl (4503599627370496.5) returns 4503599627370497


Expected Results:  llroundl (2147483646.5) returns 2147483647
llroundl (2147483647.5) returns 2147483648
llroundl (2147483648.5) returns 2147483649
llroundl (4294967294.5) returns 4294967295
llroundl (4294967295.5) returns 4294967296
llroundl (4294967296.5) returns 4294967297
llroundl (6442450942.5) returns 6442450943
llroundl (6442450943.5) returns 6442450944
llroundl (6442450944.5) returns 6442450945
llroundl (8589934590.5) returns 8589934591
llroundl (8589934591.5) returns 8589934592
llroundl (8589934592.5) returns 8589934593
llroundl (12884901886.5) returns 12884901887
llroundl (12884901887.5) returns 12884901888
llroundl (12884901888.5) returns 12884901889
llroundl (17179869182.5) returns 17179869183
llroundl (17179869183.5) returns 17179869184
llroundl (17179869184.5) returns 17179869185
llroundl (25769803774.5) returns 25769803775
llroundl (25769803775.5) returns 25769803776
llroundl (25769803776.5) returns 25769803777
llroundl (1099511627774.5) returns 1099511627775
llroundl (1099511627775.5) returns 1099511627776
llroundl (1099511627776.5) returns 1099511627777
llroundl (4503599627370494.5) returns 4503599627370495
llroundl (4503599627370495.5) returns 4503599627370496
llroundl (4503599627370496.5) returns 4503599627370497


Additional info:

I can't tell where this bug comes from.  The double version of llround
performs correctly with the same set of test cases.

In my own port of the math library, I wrote an i386-specific assembly
function that essentially computes floorl(x+copysignl(0.5,x)).
Comment 2 Jakub Jelinek 2001-09-06 12:48:16 EDT
Oops, this is fixed in glibc rpms since Jun, 25th.
Comment 3 Miloslav Trmac 2004-03-08 08:45:28 EST
Fix confirmed in glibc-2.3.2-101.4.

Note You need to log in before you can comment on or make changes to this bug.