Lowest double positive value - can cout change its value? - c++

Consider two following pieces of code - the only difference between them is a single cout which prints the value eps:
http://ideone.com/0bEeHz - here the program enters and infinite loop since after the cout eps changes value to 0
#include <iostream>
int main()
{
double tmp = 1.;
double eps;
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
std::cout << "eps before: " << eps;
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
while(eps < 1.) {
tmp = eps;
eps *= 2.;
if(tmp == eps) {
printf("wtf?\n");
}
}
std::cout << "eps after: " << eps;
}
http://ideone.com/pI4d30 - here I've commented out the cout.
#include <iostream>
int main()
{
double tmp = 1.;
double eps;
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
//std::cout << "eps before: " << eps;
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
while(eps < 1.) {
tmp = eps;
eps *= 2.;
if(tmp == eps) {
printf("wtf?\n");
}
}
std::cout << "eps after: " << eps;
}
Hence, one single cout changes program logic dramatically and very surprisingly. Why is that?

I think it's a case of Section 5 (Expressions), paragraph 11
The values of the floating operands and the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.
at work, cf. this variation of the original code.
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
Calculations and comparisons performed at extended precision. The loop runs until eps is the smallest positive extended value (probably the 80-bit x87 extended type).
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
Still at extended precision, eps != 0
std::cout << "eps before: " << eps;
For the conversion to a string to print, eps is stored and converted to double precision, resulting in 0.
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
Yes, now it is.

Related

c++ quadratic equation not working properly for a code checker

I am submitting code to my university's tester, the code for me works thoroughly for the the test cases I provided.
The checker tells there are some test cases that can't pass, I am testing in visual studio, and that's exactly compatible with the online judge compiler.
The problem description:
input : Contains 3 integer numbers: a,b,c (|a,b,c|<=1000).
output; The number of the equation's roots, then all roots in an ascending order. If you cannot do this, output "-1".
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int a, b, c, delta;
double x1, x2, x;
cin >> a >> b >> c;
delta = ((b*b) - (4 * a * c));
if (a == 0) {
if (b != 0) {
x = (-(c)*1.0 / (b));
cout << 1 << " " << x;
}
else
cout << "-1";
}
else
if (delta > 0)
{
x1 = ((-(b + sqrt(delta))*1.0) / (2 * a));
x2 = ((-(b - sqrt(delta))*1.0) / (2 * a));
if (x1 <= x2) {
cout << 2 << " " << x1 << " " << x2;
}
else
cout << 2 << " " << x2 << " " << x1;
}
else if (delta == 0)
{
x = (-(b)*1.0 / (2 * a));
cout << 1 << " " << x;
}
else
cout << "-1";
return 0;
}
I can't find any test case that fails my program, please if you can find some test cases, hints whatever I am just stuck at the problem. Thanks
the example output is described as follows; intput: 1 -8 15 output: 2 3 5
If the input was -1 8 -15, this program would output 2 5 3, while the two solutions are requested to be printed in ascending order. So you need to sort them before printing. Also I'd add a newline to every output statement.
-edit-
Without knowing the exact format required and the numbers in the failing tests, we can only speculate on how to modify the posted program. Some changes, though, could be beneficial.
I/O
There isn't any check of the input. On-line judges usually give well defined input, but you can always add some test.
cin >> a >> b >> c;
if (!cin)
cout << "-1\n";
I already mentioned the newline at the end of the line, another (unknown) requirement could be a particular precision of the outputted numbers (in fixed or scientific format).
In the comments I also pointed out the particular case of -0.0 or (-0), which while beeing a perfectly valid floating point value, could be for some reason rejected by the tester. Unlikely, but possible. So you could write the first case like this:
if (a == 0)
{
if (b != 0)
{
if ( c == 0 )
x = 0.0;
else
x = double(-c) / b;
cout << "1 " << x << '\n';
}
else
cout << "-1\n";
}
precision and corner cases
In the unlikely (given the ranges of the input values) case that you are running into precision issues, you could choose other formulas (see e.g. numerically stable algorithm for solving the quadratic equation).
else if (delta > 0)
{
if ( c == 0 )
{
x1 = 0.0;
x2 = double(-b) / a;
}
else
{
if ( b > 0 )
x1 = -0.5 * (b + std::sqrt(delta)) / a;
else
x1 = -0.5 * (b - std::sqrt(delta)) / a;
x2 = c / (a * x1);
}
if (x1 > x2)
cout << "2 " << x2 << " " << x1 << '\n';
else
cout << "2 " << x1 << " " << x2 << '\n';
}
The last part really boils down to how to consider two coincident solutions.
else if (delta == 0)
{
if ( b == 0 )
x = 0.0;
else
x = -0.5 * b / a;
cout << "1 " << x << '\n';
// Assuming they don't require ("all the roots")
// cout << "2 " << x << ' ' << x << '\n';
}
The problems would likely lie in the realm of int to double conversion.
To debug this, you need to separate out your operations into distinct lines the debugger can stop on. For instance the expression -(c*1.0) is better expressed as (double)-c. It at least makes it clearer and utilizes a negation (free) and cast (more precise [linguistically] than multiplication by 1.0).
So for instance, your code would become something like this :
#include <iostream>
#include <math.h>
using namespace std;
int mainC(int argc , char** argv)
{
(void)argc;
(void)argv;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int a, b, c, delta;
double x1, x2, x;
cin >> a >> b >> c;
delta = ((b*b) - (4 * a * c));
if (a == 0) {
if (b != 0) {
/// x = (-(c*1.0) / (b));
/// separate the operation and avoid multiplication and implicit casts
x = ((double)-c);
x /= (double)b;
cout << 1 << " " << x;
}
else
cout << "-1";
}
else
if (delta > 0)
{
/// x1 = ((-(b + sqrt(delta))*1.0) / (2 * a));
/// x2 = ((-(b - sqrt(delta))*1.0) / (2 * a));
/// separate the operation and avoid multiplication and implicit casts
// discriminant
const double discrim = sqrt(delta);
x = (double)-b;
x1 = x + discrim;
x2 = x - discrim;
x1 /= (double)(2*a);
x2 /= (double)(2*a);
cout << 2 << " " << x1 << " " << x2;
}
else if (delta == 0)
{
/// x = (-(b*1.0) / (2 * a));
/// separate the operation and avoid multiplication and implicit casts
x = (double)-b;
x /= (double)(2*a);
cout << 1 << " " << x;
}
else
cout << "-1";
return 0;
}
I think default cout precision does not math to your problem. Try
std::cout << std::setprecision(10);
or greater.
Also u can try use
std::cout << std::flush

Fractions instead of decimals

So, I am Writing this little program in c++, it's made to compute various values with lines (sorry i am french, i don't know how to say it in English, but they are the lines with equation types Y = kx + t).
And I want my program to output fractions instead of decimals (2/3 instead of 0.666666666...).
Can anyone tell me how ?
I read online that there are some libraries for that purpose, can anyone help me on how to use them and/or how to implement them in my code ?
Thanks :)
#include "pch.h"
#include <iostream>
#include <string>
std::string mainAnswer;
bool endVar = false;
void lineEquationFromTwoPoints() {
mainAnswer.clear();
double Xa = 0;
double Ya = 0;
double Xb = 0;
double Yb = 0;
double Y = 0;
double X = 0;
double k = 0;
double t = 0;
std::cout << ("Enter the Coordinates of your first point in this format x y : ");
std::cin >> Xa >> Ya;
std::cout << ("Enter the Coordinates of your second point in this format x y : ");
std::cin >> Xb >> Yb;
if (Xb != Xa && Yb != Ya) {
k = (Yb - Ya) / (Xb - Xa);
t = -(Xa)*k + Ya;
if (k != 1 && t != 0) {
std::cout << ("Y = ") << k << ("x + ") << t << std::endl;
}
else if (k == 1) {
std::cout << ("Y = ") << ("x") << ("+") << t << std::endl;
}
else if (t == 0) {
std::cout << ("Y = ") << k << ("x") << std::endl;
}
}
else if (Xb == Xa) {
std::cout << ("Coordinates of the first point are Equal");
}
else if (Yb == Ya) {
std::cout << ("Coordinates of the second point are Equal");
}
else if (Xb == Xa && Yb == Ya) {
std::cout << ("Coordinates of both points are Equal");
}
}
void triangle() {
double Xa = 0;
double Ya = 0;
double Xb = 0;
double Yb = 0;
double Xc = 0;
double Yc = 0;
double Ym1 = 0;
double Xm1 = 0;
double km1 = 0;
double tm1 = 0;
double Ym2 = 0;
double Xm2 = 0;
double km2 = 0;
double tm2 = 0;
double Ym3 = 0;
double Xm3 = 0;
double km3 = 0;
double tm3 = 0;
std::cout << ("Work in progress. . . :-)") << std::endl;
}
void Choose() {
while (endVar != true) {
std::cout << ("Lines:") << std::endl;
std::cout << ("------") << std::endl << std::endl;
std::cout << ("Choose What Line Operations do You Want Me To Perform:") << std::endl;
std::cout << ("1.Formulas") << std::endl;
std::cout << ("2.Calculation of a Line's equation from 2 points") << std::endl;
std::cout << ("3.Calculation of all data in a triangle") << std::endl;
std::cout << ("Type Exit to Exit") << std::endl << std::endl;
std::getline(std::cin, mainAnswer);
if (mainAnswer == "exit" || mainAnswer == "Exit") {
std::exit;
endVar = true;
}
else if (mainAnswer == "1") {
std::cout << ("Formulas will be added Here once main program with main calculation functions will be finished") << std::endl;
}
else if (mainAnswer == "2") {
lineEquationFromTwoPoints();
}
else if (mainAnswer == "3") {
triangle();
}
else {
std::cout << ("Unexpected error occured. Please relaunch program.");
std::exit;
}
}
}
int main()
{
Choose();
return 0;
}
A nice way to approximate a float with a fraction is to used continued fractions. In the following code, epsis the desired precision. xis assumed to be strictly positive.
#include <iostream>
#include <iomanip>
#include <cmath>
#include <tuple>
#include <vector>
#include <cmath>
// Continued fraction
std::pair<int, int> fract_cont (double x, double eps = 1.0e-3) {
std::vector<int> a;
std::vector<int> b;
a.push_back(1);
b.push_back(0);
int q = int(x);
a.push_back(q);
b.push_back(1);
double err = x - q;
double e = (x != q) ? 1.0 / (x - q) : 0.0;
int i = 1;
while (std::abs(err) > eps) {
i++;
q = int (e);
e = 1.0 / (e - q);
a.push_back (q * a[i-1] + a [i-2]);
b.push_back (q * b[i - 1] + b[i-2]);
err = x - double (a[i]) / b[i];
}
return std::make_pair(a[i], b[i]);
}
int main() {
int a, b;
double x = 4 * atan(1.0);
std::tie (a,b) = fract_cont(x);
std::cout <<"Pi = " << std::setprecision(9) << x << " ~= " << a << "/" << b << "\n";
return 0;
}
Detailed information on continued fractions is available on Wikipedia for example.
If you don't need a high precision or if you assume that the denominators will be small, you can use a brute force approach instead, simply incrementing the denominator b.

An error: Vector subscript out of range, drill from book "Programming Principles And Practice Using C++" below the session 4.7 Language features

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
double sum(std::vector<double>); //sum of all the values in meter
double conversion(double, std::string); //convert from other units to meter
void print_largest_value(double, std::string);
void print_smallest_value(double, std::string);
int main()
{
std::vector<double> temps; //for storing the numbers entered
std::vector<std::string> units; //for storing the units entered
std::vector<double> vals; //for storing values in meter converted
double temp, smallest_val, largest_val, smallest_temp, largest_temp;
std::string unit = " ", unit_of_smallest, unit_of_largest;
int i;
for (temp, i = 0; std::cin >> temp >> unit; ++i) {
if (unit == "cm" || unit == "in" || unit == "ft" || unit == "m") {
temps.push_back(temp);
units.push_back(unit);
}
else {
std::cout << "reject value\n"; //value get rejected if unit not valid
--i;
continue;
}
vals[i] = conversion(temp, unit); //error: Array index out of bounds
std::cout << temp << unit << '\n';
std::cout << vals[i] << " meter(s)\n";
if (i == 0) {
smallest_val = vals[i];
smallest_temp = temps[i];
unit_of_smallest = unit[i];
print_smallest_value(temps[i], units[i]);
}
if (i == 0) {
largest_val = vals[i];
largest_temp = temps[i];
unit_of_largest = unit[i];
print_largest_value(temps[i], units[i]);
}
if (smallest_val > vals[i]) {
smallest_val = vals[i];
smallest_temp = temps[i];
unit_of_smallest = unit[i];
print_smallest_value(temps[i], units[i]);
}
if (largest_val < vals[i]) {
largest_val = vals[i];
largest_temp = temps[i];
unit_of_largest = unit[i];
print_largest_value(temps[i], units[i]);
}
}
std::cout << "the sum is: " << sum(vals) << " meter(s)\n";
std::cout << "the largest value entered is " << largest_temp << unit_of_largest << '\n';
std::cout << "the smallest value entered is " << smallest_temp << unit_of_smallest << '\n';
}
double sum(std::vector<double> v) {
double sum = 0;
for (double x : v)
sum += x;
return sum;
}
double conversion(double val, std::string unit) {
if (unit == "cm")
val /= 100;
else if (unit == "in")
val /= 39.3701;
else if (unit == "ft")
val /= 3.28084;
return val;
}
void print_largest_value(double val, std::string unit) {
std::cout << "the largest value so far: " << val << unit << '\n';
}
void print_smallest_value(double val, std::string unit) {
std::cout << "the smallest value so far: " << val << unit << '\n';
}
/*
7. Add a unit to each double entered; that is, enter values such as 10cm, 2.5in, 5ft, or 3.33m. Accept the four units: cm,
m, in, ft. Assume conversion factors 1m == 100cm, 1in == 2.54cm, 1ft == 12in. Read the unit indicator into a string.
You may consider 12 m (with a space between the number and the unit) equivalent to 12m (without a space).
8. Reject values without units or with “illegal” representations of units, such as y, yard, meter, km, and gallons.
9. Keep track of the sum of values entered (as well as the smallest and the largest) and the number of values entered. When
the loop ends, print the smallest, the largest, the number of values, and the sum of values. Note that to keep the sum, you
have to decide on a unit to use for that sum; use meters.
*/

Compute cos(x) to 0 when x is 90 degree or pi/2 radian in C++

# include <iostream>
# include <math.h>
# include <cstdlib>
using namespace std;
double cosin_value( double value);
double sin_value( double value);
double big_degree (double value);
double big_radian (double value);
double x;
double value;
double degree;
double radian;
const double PI = 3.14159;
char choice;
char yes ;
int main()
{
cout << "Please enter an angle value => ";
cin >> value;
cout << "Is the angle in Degree or Radian?" << endl;
cout << "\t" << "Type D if it is in Degree" << endl;
cout << "\t" << "Type R if it is in Radian" << endl;
cout << "Your response => ";
cin >> choice; //degree or radian?
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(10);
if (choice == 'D' || choice == 'd')
{
big_degree (value);
cout << " " << "sin(x) = " << "\t" << sin_value(degree) << endl;
cout << " " << "cos(x) = " << "\t" << cosin_value(degree) << endl;
cout << " " << "tan(x) = " << "\t" << sin_value(degree)/cosin_value(degree) << endl;
}
else if (choice == 'R' || choice == 'r')
{
cout << " " << "sin(x) = " << "\t" << sin_value(radian) << endl;
cout << " " << "cos(x) = " << "\t" << cosin_value(radian) << endl;
cout << " " << "tan(x) = " << "\t" << sin_value(radian)/cosin_value(radian) << endl;
}
return 0;
}
// Sine,cosine functions
// angle -360<value<360
double sin_value( double value)
{
int count=1;
double sine, num, dem, sign, term;
sine=0;
sign = 1;
num = value;
dem = count;
while ( count <= 20 )
{
term = (num/dem);
sine = sine + term*sign;
num = num*value*value;
count = count + 2;
dem = dem * count * (count-1);
sign = -sign;
}
return (sine);
}
double cosin_value( double value)
{
int count=0;
double cosine, num, dem, sign, term;
cosine=0;
sign = 1;
num = 1;
dem = 1;
while ( count <= 20 )
{
term = (num/dem);
cosine = cosine + term*sign;
num = num*value*value;
count = count + 2;
dem = dem * count * (count-1);
sign = -sign;
}
return (cosine);
}
double big_degree (double value)
{
int result;
const int angle=360;
if (value >= 360 || value <= -360)
{
result=value/angle;
degree=(value-(result* angle))*PI/180;
}
else
{
degree = (value*PI)/180;
}
return (degree);
}
double big_radian (double value)
{
int result;
if (value >= 2*PI || value <= -2*PI)
{
result=value/(2*PI);
radian=(value-(result* 2*PI));
}
else
{
radian = value;
}
return (radian);
}
Hi, this is basically the whole program I wrote for calculating trigonometric value using the extent knowledge I knew in C++ as a beginner. For a better view, you can refer to this link regarding my code above :codepad.org
the line starting from line 114 onwards are the function that I created. There's a problem there where how can I compute my cosx to be 0 when the value is 90 degree or pi/2 radian?
since the program will still calculate tanx for me even the value is 90 degree.
Let's say by giving value 90 degree to the program, it will give me the value of 0.0000013268 instead of 0.000000
sorry, since I'm just a beginner, the code will look weird for you guys.
I appreciate your guides!
double big_degree(double value) means when the value is >= 360 or <= -360*
I do not allocate any heap space in my brain for digits of pi, but I do remember that atan(1) == pi / 4.
Change your PI constant like so:
const double PI = atan(1) * 4;
Taking your code, making that change, I get
Please enter an angle value => 90
Is the angle in Degree or Radian?
Type D if it is in Degree
Type R if it is in Radian
Your response => d
sin(x) = 1.0000000000
cos(x) = 0.0000000000
tan(x) = 15555226593901466.0000000000
const double PI = 3.14159;
The more precise you make this definition, the more close to 0 will the value of cos PI/2 get!
If you get the input itself in radians, there also the same criteria applies.
The problem isn't your code. The input you have given is not sufficiently accurate. Calculate the proper value of pi/2, and you will get a sufficiently accurate value.Also, if you want to round off the values you can use#rounded off value=Math.Round(#old value, 4)
My soulution:
double mySin(double x)
{
if (fmod(x, std::numbers::pi) == 0)
return 0;
return sin(fmod(x, std::numbers::pi * 2.0));
}
double myCos(double x) { return mySin(x + std::numbers::pi / 2); }
myCos(std::numbers::pi / 2) == 0 //True
myCos(std::numbers::pi) == -1 //True
myCos(std::numbers::pi * 2) == 1 //True

Why does the compiler say pow(n,k) ambiguous in this code?

When compiling the following code under Xcode 4.5 (Mac), compilation fails with the following error message:
call to 'pow' is ambiguous
Why? Thanks!
#include <iostream>
#include <cmath>
#include <limits>
using namespace std;
int main()
{
cout << "\tSquare root calculator using an emulation the ENIAC's algorithm." << endl
<< endl;
long long m;
while ((cout << "Enter a positive integer:" << endl)
&& (!(cin >> m) || m < 0 || m > 9999999999)) //10-digit maxium
{
cout << "Out of range.";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
again:
long long l = m;
//Find out how big the integer is and adjust k accordingly.
int order = -1;
long long temp = m;
do
{
temp /= 10;
order++;
} while (temp/10);
int k = order/2;
//Step 1
long long a = -1;
do
{
a+=2;
m -= a*pow(100,k);
} while (m >= 0);
while (k > 0)
{
k--;
//Step 2
if (m < 0)
{
a = 10*a+9;
for (;m < 0;a -= 2)
{
m += a*pow(100,k);
}
a += 2;
}
//Step 3
else
{
a = 10*a-9;
for(;m >= 0;a += 2)
{
m -= a*pow(100,k);
}
a -= 2;
}
}
//Step 4
cout << endl << "The square root of " << l << " is greater than or equal to "
<< (a-1)/2 << " and less than " << (a+1)/2 << "." << endl << endl;
while ((cout << "Enter a positive integer to calculate again, or zero to exit." << endl)
&& (!(cin >> m) || m < 0 || m > 9999999999))
{
cout << "Out of range.";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (m > 0) goto again;
return 0;
}
As you can see here there is no pow(int,int);
pow
<cmath>
double pow ( double base, double exponent );
long double pow ( long double base, long double exponent );
float pow ( float base, float exponent );
double pow ( double base, int exponent );
long double pow ( long double base, int exponent );
This link looks like it answers your question:
http://bytes.com/topic/c/answers/727736-ambiguous-call-pow
It looks like the pow() function doesn't like integers.