Bug 15010 - std::sin produces wrong results when rounding mode set
Summary: std::sin produces wrong results when rounding mode set
Status: RESOLVED DUPLICATE of bug 3976
Alias: None
Product: glibc
Classification: Unclassified
Component: math (show other bugs)
Version: 2.15
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2013-01-10 19:07 UTC by Joshua Hopp
Modified: 2014-06-13 19:04 UTC (History)
1 user (show)

See Also:
Host: x86_64
Target: x86_64
Last reconfirmed:
fweimer: security-


Note You need to log in before you can comment on or make changes to this bug.
Description Joshua Hopp 2013-01-10 19:07:48 UTC
If the rounding mode is set (other than FE_TONEAREST), the sine function gives wrong results for some input values. In fact, the results are not even in the interval of [-1, 1] but in the dimension of ±1e50. Try this:

//--- snip ---
#include <random>
#include <limits>
#include <cmath>
#include <iostream>
#include <cfenv>

const unsigned ROUNDS = 1000000;

int main () {
	std::fesetround(FE_DOWNWARD); // or FE_UPWARD

	// initialize random number generator
	std::random_device rd;
	std::mt19937 rand(rd());

	// set bounds for input value "x"
	double limit_min = -10;
	double limit_max = 10;
	std::uniform_real_distribution<double> dis(limit_min, limit_max);

	for (int i=0; i<ROUNDS; i++) {

		// create a random number "x"
		double input_value = dis(rand);

		// calculate "sin(x)"
		double output_value = std::sin(input_value);

		// if "sin(x)" is out of bounds, print 
		if (output_value < -1 || output_value > 1) {
			std::cout << "sin(" << input_value << ") != " << output_value << std::endl;
	return 0;
//--- snap ---

sin(6.28305) != -1.0016
sin(-6.98816) != 1.91558e+53
sin(-5.40876) != -1.38604e+51

Compile with "g++ -std=c++11". Other functions in cmath (such as exp()) might be affected as well, but harder to test.

Kernel version: 3.2.0-29-generic
gcc version: gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-11precise2) 
ld version: GNU ld (GNU Binutils for Ubuntu) 2.22
Comment 1 Andreas Jaeger 2013-01-10 19:22:58 UTC
I run your program with glibc 2.17 and this seems to be fixed:
aj@byrd:/tmp> g++ t.cc -lm -O2 -std=gnu++11
aj@byrd:/tmp> ./a.out 

This should have been fixed already for glibc 2.16 - it's a duplicate of bug 3976.

*** This bug has been marked as a duplicate of bug 3976 ***