C++ : Working of sine function [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying to plot a sine curve in C++ and came across something interesting.
I have a function that returns sine value of a value in degree
double sind(double a)
{
return sin(a*3.14159/180);
}
Now in the main function
sind(18)==sind(18)?cout<<1:cout<<0;
I write the above code. The result seems to be false and it prints 0 on the console.
But according to me sin(18) and sin(18) are equal. So what is happening in the computer's mind?
Also if I want to check equality of two sine values how would I go about it?

On the PC, at least as of old, floating points values were calculated with 80 bits, but were rounded down to 64 bits for main memory. When the compiler recognizes that it can reuse an 80-bit result for an 80-bit comparison you can get baffling results like this. And yes, it's permitted by the Holy Standard.
By the way, void main is not valid. This means the code has Undefined Behavior and in principle can do anything whatsoever, including doing nothing, or what you expect. In practice it's not that bad, it just makes the code non-portable, but still, don't do it: it's silly to add one character in order to make the code non-portable, so write int main.

Also if I want to check equality of two sine values how would I go about it?
There is a very good example of a floating point "almost_equal" function here
by request, code copied from original source:
#include <cmath>
#include <limits>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <algorithm>
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
almost_equal(T x, T y, int ulp)
{
// the machine epsilon has to be scaled to the magnitude of the values used
// and multiplied by the desired precision in ULPs (units in the last place)
return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
// unless the result is subnormal
|| std::abs(x-y) < std::numeric_limits<T>::min();
}
int main()
{
double d1 = 0.2;
double d2 = 1 / std::sqrt(5) / std::sqrt(5);
if(d1 == d2)
std::cout << "d1 == d2\n";
else
std::cout << "d1 != d2\n";
if(almost_equal(d1, d2, 2))
std::cout << "d1 almost equals d2\n";
else
std::cout << "d1 does not almost equal d2\n";
}

Related

get the memory address instead of double value [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I just practice on c++ and want to get the area of circle from a given radius but the result giving me a memory address instead of value
#include <iostream>
#include<math.h>
using namespace std;
int main() {
double a, n, r;
n = 3.14159;
cin >> r;
a = pow(r,r) * n;
cout << "A=" << a<<endl;
}
while the input is 100.64 i got the output
A=1.13759e+202
but the result giving me a memory address instead of value
while the input is 100.64 i got the output
A=1.13759e+202
Your assumption is wrong. That is not a "memory address". That is the correct result of π × rʳ.
However, your calculation is not the correct one for area of a circle. Correct formula is π × r².
Bonus hint: r * r is typically better than calling std::pow.
Bonus hint 2: C++20 has constant std::numbers::pi in the <numbers> header. It provides you with the closes representable approximation of π.

Reason for Overflow (G++ vs Clang++) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
When I'm compiling the following piece of C++ code using Clang++ and G++
void ScaleFactor(float32_t scale, int32_t &factor) {
factor = floor(log2(abs(scale))+1)
cout << factor << endl;
}
where the value of scale equals 0.234375 and factor is passed by reference to an integer variable in another function, I'm getting the following different outputs for factor while debugging using GDB
(int32_t &) #0x7fffffffdaa0: -2147483648 (Clang++)
(int32_t &) #0x7fffffffda9c: -2 (G++)
But, on replacing abs() with fabs() each output matches with the desired output
(int32_t &) #0x7fffffffdb90: -2 (Clang++)
(int32_t &) #0x7fffffffdddc: -2 (G++)
What might be the reason for this discrepancy?
See the answer to this post. abs is generally for integers and fabs is for floating point types. However, it looks like G++ implementation of abs will handle floats, too.
Does this code produce the same results? It does not seem to, for me: https://godbolt.org/z/Wj9v6j
#include <iostream>
#include <cmath>
using namespace std;
using float32_t = float;
void ScaleFactor(float32_t scale, int32_t &factor) {
factor = floor(log2(abs(/*(int)*/scale))+1);
cout << factor << endl;
}
int main() {
int32_t result;
ScaleFactor(0.234375f, result);
return 0;
}
If it does not, are you sure that something else is not going wrong here? Maybe you are including the C versions of the math functions, where there is a difference between abs and fabs, when building with clang?
The weird result you get is exactly what I get if I cast the float to int when passing it to abs, exactly what you would expect if you were using the C version of abs.

Why does floor(pow(64,1.0/3)) return 3 but print 4 when the floor() is removed in C++? [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 6 years ago.
I need to find the floor nth root of a given number(x). x can be as large as 1e12 and n can be as large as 50. floor(pow(64,1.0/3)) returns 3, please help me with this problem, if not can you please suggest an alternative taking the keeping in mind?
Edit: I know its about floating point precision, I am asking what the alternative should be in such situations.
Even the following code returns True
double x = pow(64,1.0/3);
return x==(int)x;
You are dealing with good old floating-point imprecision. See What is the numerical stability of std::pow() compared to iterated multiplication?, and especially Pascal Cuoq's answer, for an in-depth explanation why the result of std::pow in particular will be imprecise. Because of rounding errors, you will occasionally get a result that is ever so slightly less than 4, and so std::floor will round down to 3.
The answer I linked above says:
A quality implementation of pow will give you 1 ULP of accuracy for its result, and the best implementations will “guarantee” 0.5 ULP.
ULP here refers to the Unit of Least Precision or Unit in the Last Place. Knowing about this error, you can increase the std::pow() result before calling std::floor. A good way to do this is using std::nextafter, which gives you the next-larger representable floating-point value (i.e., 1 ULP up). I think that if Pascal's statement on the precision of std::pow() holds, calling nextafter once should put you back above 4, in your particular example. Here's the code I recommend:
template <typename T>
T floorroot2(T x, T e)
{
const auto r = std::pow(x, T(1.0)/e);
return std::floor(std::nextafter(r, r+1));
}
That works for me (live example), but if you want to be extra sure if you don't trust your library's pow implementation, you may want to add 2 ULPs, i.e. call nextafter(nextafter(r, r+1), r+1).
#include <iostream>
#include <cmath>
using namespace std;
template<class Type>
Type compute(Type v1, Type v2, Type v3)
{
return std::floor(std::pow(v1, v2 / v3));
}
int main() {
std::cout << compute<float>(64, 1, 3) << std::endl;
std::cout << compute<double>(64, 1, 3) << std::endl;
std::cout << compute<long double>(64, 1, 3) << std::endl;
}
expected output:
4
3
4

Detect Integer Overflow Using If Statement [duplicate]

This question already has answers here:
How do I detect unsigned integer overflow?
(31 answers)
Closed 6 years ago.
Edit (IMPORTANT): This question was more specific than the question this was marked as a duplicate against. This was asking how to do it with a boolean function. But now I know that it just doesn't work like that. This question shows that a + b = c can only be overflow checked if you write if(c - b == a) and that there is no operator independent way of checking.
Once the overflow happened, you cannot detect it
-lorro
I have been looking for a way to detect integer overflow in C++ using an if statement.
Possible pseudo code:
#include <iostream>
#include <...>
using namespace std;
bool isOverflow(...);
int main()
{
int a = INT_MAX + 1;
if (isOverflow(...))
{
cout << "Overflow" << endl;
}
else
{
cout << "No Overflow" << endl;
}
return 0;
}
bool isOverflow
{
...
}
OK to be honest this pseudo code preference may not work, but i've seen this question asked many times and have not found any useful answers. It may require unsigned or unsigned long long, although I'm not necessarily encouraging the use of those.
EDIT:
I would like to use it with a multiplication sentence with 3 numbers:
a * a * b
I am aware that there is a pow function in <math.h> but that's off topic.
I am also aware that if I want an accurate int result from pow I would use:
int(pow(base, index) + 0.5)
It depends on what sort of operation you are using and what are the types of the operands.
e.g. if you want to detect an overflow after addition, and both operands are unsigned integers, then an overflow will have occurred if the result is less than the sum of both operands.
bool overflow;
if (a+b < a)
overflow = true;
else
overflow = false;
For signed integers, you can refer to the excellent post here

Shift operator fast or not fast? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
What is the faster between the two following code? why?
In which case one can be preferred to the other?
double x = (a + b) >> 1
double x = (a + b) / 2.0
These do different things so pick the one with the functionality you like: Truncating the result down or returning the 0.5 fraction.
"Premature optimization is root of all evil". Use what is more readable, when you have perfomance issue first look for algorithms and data structures, where you can get most perfomance gain, then run profiler and optimize where is necessary.
As others have said, the two statements produce different results, especially if (a + b) is an odd value.
Also, according to the language, a and b must be integral values in order to satisfy the shifting operation.
If a and b differ in type between the two statements, you are comparing apples to elephants.
Given this demo program:
#include <iostream>
#include <cstdlib>
#include <cmath>
using std::cout;
using std::endl;
int main(void)
{
const unsigned int a = 5;
const unsigned int b = 8;
double x = (a + b) >> 1;
cout << x << endl;
double y = (a + b) / 2.0;
cout << y << endl;
return EXIT_SUCCESS;
}
The output:
6
6.5
Based on this experiment, the comparison is apples to oranges. The statement involving shifting is a different operation that dividing by a floating point number.
As far as speed goes, the second statement is slower because the expression (a + b) must be converted to double before applying the division. The division is floating point, which may be slow on platforms without hardware floating point support.
You should not concern yourself on the execution speed of either statement. Of more importance is the correctness and robustness of the program. For example, the two statements above provide different results, which is a very important concern for correctness.
Most Users would wait for a program to produce correct results than have a quick program producing incorrect results or behavior (nobody is in a hurry for a program to crash).
Management would rather you spend time completing the program than wasting time optimizing portions of the program that are executed infrequently.
If a or b is a double or float, shifting will produce incorrect results.