i386/133583: fma does not respect rounding mode using extended
precision
Abramo Bagnara
abramo.bagnara at gmail.com
Fri Apr 10 15:40:02 PDT 2009
>Number: 133583
>Category: i386
>Synopsis: fma does not respect rounding mode using extended precision
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-i386
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Apr 10 22:40:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Abramo Bagnara
>Release: 7.1
>Organization:
>Environment:
FreeBSD freebsd.homenet.telecomitalia.it 7.1-RELEASE FreeBSD 7.1-RELEASE #0: Thu Jan 1 14:37:25 UTC 2009 root at logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
>Description:
After fpsetprec(FP_PE) libc fma does not respect rounding mode.
>How-To-Repeat:
$ gcc bug.c -lm
$ ./a.out
Exact result: 9973859.79298831405913006165064871311187744140625
Default precision, DOWNWARD +* : 9973859.79298831336200237274169921875
Default precision, UPWARD +* : 9973859.79298831522464752197265625
Default precision, DOWNWARD fma: 9973859.79298831336200237274169921875
Default precision, UPWARD fma: 9973859.79298831522464752197265625
Extended precision, DOWNWARD +* : 9973859.79298831336200237274169921875
Extended precision, UPWARD +* : 9973859.79298831522464752197265625
Extended precision, DOWNWARD fma: 9973859.7929883114993572235107421875
Extended precision, UPWARD fma: 9973859.79298831336200237274169921875
>Fix:
Patch attached with submission follows:
#include <math.h>
#include <fenv.h>
#include <stdio.h>
#ifdef __FreeBSD__
#include <ieeefp.h>
#endif
double to = 8248384;
double x = 2871;
double y = 601.00166944908187360852025449275970458984375;
// Exact result is: 9973859.79298831405913006165064871311187744140625
int main() {
printf("Exact result: 9973859.79298831405913006165064871311187744140625\n");
fesetround(FE_DOWNWARD);
printf("Default precision, DOWNWARD +* : %.1000g\n", to + x * y);
fesetround(FE_UPWARD);
printf("Default precision, UPWARD +* : %.1000g\n", to + x * y);
fesetround(FE_DOWNWARD);
printf("Default precision, DOWNWARD fma: %.1000g\n", fma(x, y, to));
fesetround(FE_UPWARD);
printf("Default precision, UPWARD fma: %.1000g\n", fma(x, y, to));
#ifdef __FreeBSD__
fpsetprec(FP_PE);
fesetround(FE_DOWNWARD);
printf("Extended precision, DOWNWARD +* : %.1000g\n", to + x * y);
fesetround(FE_UPWARD);
printf("Extended precision, UPWARD +* : %.1000g\n", to + x * y);
fesetround(FE_DOWNWARD);
printf("Extended precision, DOWNWARD fma: %.1000g\n", fma(x, y, to));
fesetround(FE_UPWARD);
printf("Extended precision, UPWARD fma: %.1000g\n", fma(x, y, to));
#endif
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-i386
mailing list