How to make two double variables with different length become equal - c++

I'm new to Visual C++, i have two double variables, let say AA = 10.650406 while b = 10.65040606439, how can i make them equal?
here is an example
AA = 10.650406;
if (a == tempfunc(zz))
execute TRUEFUNCTION
else
exceute FALSEFUNCTION
the variable AA is a double while the function tempfunc return double, if the value AA is 10.650406, while the return value of tempfunc is 10.65040606439. the question is how can make these value equal so i can execute the function TRUEFUNCTION

The typical solution is to compare the difference, using an "epsilon value". Something like
const double eps = 0.000001; // Adjust this to match the "perecision" you need.
if (abs(a-b) < eps)
{
// Values are almost equal
}

I guess your question is: how to have a check that would be true for these two numbers, but not for all..:
10.123 == 10.1234 (TRUE)
10.123 == 11.123 (FALSE)
if you have a fixed number of digits after the decimal separator (6 in your example), you could do this:
int a2 = a * 10e6;
int b2 = b * 10e6; // (conversion to integers; so the digits smaller than the 6th digit will be removed)
Now you can check:
if (a2 == b2)
{
//do your thing
}
in short:
if ( ((int) a*10e6) == ((int) b*10e6))
{
//do your thing
}

Related

I need to get a random number in the range from a to b with n decimal places

I need a function that returns me a random number with n decimal places
Example:
int aleatorio(int li, int ls)
{
return rand()%(ls+1-li)+li;
}
What i want is:
float new_random(int start, int final, int number_decimals)
{
return // What should I write here?
}
if I would call this function 5 times like this::
new_random(0, 5, 4);
The exit would be:
0.2344
3.4356
2.8435
4.2435
I do not want to use this, because I need numbers of 4 exact decimal places since I will not use them to print, but you will have others:
cout << setprecision(4) << 4.24359675967 << endl; //I do not want this
I need numbers of 4 exact decimal places
Then you cannot use finite precision binary floating point (i.e. float, double or long double) because those types cannot exactly represent all of the values with 4 decimal places.
A solution is to use arbitrary precision floating point, and another is to use fixed point. C++ standard doesn't provide arbitrary precision types nor fixed point types. Another approach is to give up the requirement of exactly representing those values and accept the almost exact values that are achievable with limited precision.
Try this for a Java solution. Multiply the start and finish by 1000, generating ints between the range and then divide the resultant number by 1000 as a double.
int start = 20;
int finish = 30;
int count = 10;
Random r = new Random();
r.ints(start * 1000, finish * 1000).filter(n -> n % 10 != 0)
.limit(count).mapToDouble(n -> n / 1000.)
.forEach(System.out::println);
prints something like this.
21.186
26.983
25.345
20.764
27.911
21.139
24.679
27.722
29.443
28.675
Or as a method supplying the starting number, ending number and precision.
for (int i = 0; i < 10; i++) {
System.out.println(newRandom(start,finish,4));
}
static Random r = new Random();
public static Double newRandom(int start, int finish, int precision) {
int f = (int)Math.pow(10,precision);
return r.ints(start * f, finish * f).filter(n -> n % 10 != 0)
.limit(1).mapToDouble(n -> n / (double)f).findFirst().getAsDouble();
}
Prints something like this.
28.4444
25.0259
29.5611
25.6445
25.4977
28.5124
28.9709
23.4835
27.9766
23.9438
You can generate an integer number N between start and final * 10^number_decimals and then return N / 10^number_decimals
Eg. start = 0, final = 5, number_decimals = 4 ==> N in [0 - 50000] ==> N/10000 in [0.0000 - 5.0000]
float new_random(int start, int final, int number_decimals) {
return aleatorio(start, final*pow10(number_decimals))/number_decimals;
}
You can define pow10 as:
int pow10(int p) {
if (p == 0) return 1;
else return 10 * pow10(p-1);
}

Comparing floating-point numbers (floats or doubles) for min/max

How to compare two different floats, to a certain degree of accuracy. I know that there are very slight imprecisions while using floats or doubles in any programming language, but which may however, be enough to cause this comparison of floats a < b to return a different value than it actually should.
I was solving a problem from the UVa Online Judge which gave me a Wrong Answer many times. It took few float values as input, albeit, to 2 decimal places. I figured out the makeshift solution, which was by splitting the input and converting it to ints, but I wouldn't prefer to use that always.
So my question is, what's the best way to compare whether a float a is lesser (or greater) than a float b, provided that the inputs of a and b are given correct to n decimal places, in this case, 2?
The language I prefer is C++.
Use std::numeric_limits<T>::epsilon() to check whether two numbers are almost equal. If you want to know whether one is greater/less you should also take into account the relative tolerance.
#include <cmath>
#include <limits>
template < typename T >
bool fuzzy_compare(T a, T b)
{
return std::abs(a - b) < std::numeric_limits<T>::epsilon();
};
Just use math:
#define PREC 0.01 //(1/pow(10,n)), n = 2
float c = a-b;
if (abs(c) < PREC) {
printf("a equals b");
} else if(c < 0){
printf("b is grater than a");
} else
printf("a is grater than b");
}
Use the setprecison() operator. The number you put in between the parentheses will determine how many numbers pass the decimal will be included in the output. Be sure to include the iomanip library.
Comparing floats is alway a tricky Here is a more complicated example, showing why you should use std::numeric_limits<T>::epsilon().
The first line returns true, but the second returns false (on my machine).
float64_t CalculateEpsilon ()
{
float64_t l_AllowedInaccuray = 1; // 1.1, 0.9
int32_t significantDecimalPlaces = 2;
return ( l_AllowedInaccuray * pow ( 0.1, significantDecimalPlaces ) );
}
bool IsEqual ( float64_t lhs, float64_t rhs )
{
float64_t l_Epsilon = CalculateEpsilon ();
float64_t l_Delta = std::abs ( lhs - rhs );
return l_Delta <= l_Epsilon;
}
int32_t main ()
{
std::cout << IsEqual ( 107.35999999999999, 107.350 ); //returns true
std::cout << IsEqual ( 107.359999999999999, 107.350 ); //returns false
return 0;
}

Recursive Binary Conversion C++

I am fairly new to C++. I am trying to write a recursive binary function. The binary output needs to be 4 bits, hence the logic around 15 and the binary string length. It converts to binary correctly, the problem I am having is ending the recursive call and returning the binary string to the main function. It seems to just backwards through the call stack? Can someone help me understand what is going on?
Assuming using namespace std. I know this is not good practice, however it is required for my course.
string binary(int number, string b){
if (number > 0 && number < 15){
int temp;
temp = number % 2;
b = to_string(temp) + b;
number = number / 2;
binary(number, b);
}
else if (number > 15){
b = "1111";
number = number - 15;
binary(number, b);
}
else if (number == 15){
b = "11110000";
return b;
}
//should be if number < 1
else{
int s = b.size();
//check to make sure the binary string is 4 bits or more
if (s >= 4){
return b;
}
else{
for (int i = s; i < 4; i++){
b = '0' + b;
}
return b;
}
}
}
You have your function returning a string, but then you require the user to supply an initialized string for you, and you throw away the return value except for the base cases of 15 and 0. The rest of the time, your actual communication is using the parameter b. This multiple communication will cause some headaches.
I also note that you return a properly padded 4-bit number in normal cases; however, you force a return an 8-bit 15 for the exact value 15. Is this part of the assignment specification?
The logic for larger numbers is weird: if the amount is more than 15, you return "1111" appended to the representation for the remainder. For instance, 20 would return as binary(5) followed by "1111", or "1011111", which is decidedly wrong. Even stranger, it appears that any multiple of 15 will return "11110000", since that clause (== 15) overwrites any prior value of b.
I suggest that you analyze and simplify the logic. There should be two cases:
(BASE) If number == 0, return '0'
(RECUR) return ['1' (for odd) else '0'] + binary(number / 2)
You also need a top-level wrapper that checks the string length, padding out to 4 digits if needed. If the "wrapper" logic doesn't fit your design ideas, then drop it, and work only with the b parameter ... but then quit returning values in your other branches, since you don't use them.
Does this get you moving?

How does that recursive function work?

Might be a very basic question but I just got stuck with it. I am trying to run the following recursive function:
//If a is 0 then return b, if b is 0 then return a,
//otherwise return myRec(a/2, 2*b) + myRec(2*a, b/2)
but it just gets stuck in infinite loop. Can anybody help me to run that code and explain how exactly that function works? I built various recursive functions with no problems but this one just drilled a hole in my head.
Thanks.
Here is what I tried to do:
#include<iostream>
int myRec(int a, int b){
if (a==0){
return b;
}
if (b==0){
return a;
}
else return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
int main()
{
if (46 == myRec(100, 100)) {
std::cout << "It works!";
}
}
Well, let us mentally trace it a bit:
Starting with a, b (a >= 2 and b >= 2)
myRec(a/2, 2*b) + something
something + myRec(2*a', b'/2)
Substituting for a/2 for a' and 2*b for b', we get myRec(2*(a/2), (b*2)/2), which is exactly where we started.
Therefore we will never get anywhere.
(Note that I have left out some rounding here, but you should easily see that with this kind of rounding you will only round down a to the nearest even number, at which point it will be forever alternating between that number and half that number)
I think you are missing on some case logic. I last program in C ages ago so correct my syntax if wrong. Assuming numbers less than 1 will be converted to zero automatically...
#include<iostream>
int myRec(int a, int b){
// Recurse only if both a and b are not zero
if (a!=0 && b!=0) {
return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
// Otherwise check for any zero for a or b.
else {
if (a==0){
return b;
}
if (b==0){
return a;
}
}
}
UPDATE:
I have almost forgot how C works on return...
int myRec(int a, int b){
if (a==0){
return b;
}
if (b==0){
return a;
}
return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
VBA equivalent with some changes for displaying variable states
Private Function myRec(a As Integer, b As Integer, s As String) As Integer
Debug.Print s & vbTab & a & vbTab & b
If a = 0 Then
myRec = b
End If
If b = 0 Then
myRec = a
End If
If a <> 0 And b <> 0 Then
myRec = myRec(a / 2, 2 * b, s & "L") + myRec(2 * a, b / 2, s & "R")
End If
End Function
Sub test()
Debug.Print myRec(100, 100, "T")
End Sub
Running the test in Excel gives this (a fraction of it as it overstacks Excel):
T: Top | L: Left branch in myRec | R: Right branch in myRec
The root cause will be the sum of the return which triggers more recursive calls.
Repeating of the original values of a and b on each branch from level 2 of the recursive tree...
So MyRec(2,2) = MyRec(1,4) + MyRec(4,1)
And MyRec(1,4) = MyRec(.5,8) + MyRec(2,2)
So MyRec(2,2) = MyRec(.5,8) + MyRec(2,2) + MyRec(4,1)
Oops.
(The .5's will actually be zeroes. But it doesn't matter. The point is that the function won't terminate for a large range of possible inputs.)
Expanding on gha.st's answer, consider the function's return value as a sum of expressions without having to worry about any code.
Firstly, we start with myRec(a,b). Let's just express that as (a,b) to make this easier to read.
As I go down each line, each expression is equivalent, disregarding the cases where a=0 or b=0.
(a,b) =
(a/2, 2b) + (2a, b/2) =
(a/4, 4b) + (a, b) + (a, b) + (4a, b/4)
Now, we see that at a non-terminating point in the expression, calculating (a,b) requires first calculating (a,b).
Recursion on a problem like this works because the arguments typically tend toward a 'base case' at which the recursion stops. A great example is sorting a list; you can recursively sort halves of the list until a list given as input has <= 2 elements, which is trivial without recursion. This is called mergesort.
However, your myRec function does not have a base case, since for non-zero a or b, the same arguments must be passed into the function at some point. That's like trying to sort a list, in which half of the list has as many elements as the entire list.
Try replacing the recursion call with:
return myRec(a/2, b/3) + myRec(a/3, b/2);

How can I check if std::pow will overflow double

I have a function that deals with arbitrarily large grids. I need to compute if a grid to the power of another number will fit into a double due to using std::pow. If it cannot, I want to take a different branch and use gnu multiprecision library instead of normal.
Is there a quick way to see if:
int a = 1024;
int b = 0-10;
if(checkPowFitsDouble(a, b)) {
long c = static_cast<long>(std::pow(a, b)); //this will only work if b < 6
} else {
mpz_t c; //yada yada gmp
}
I am completely stumped on checkPowFitsDouble; perhaps there is some math trick I don't know of.
A common trick to check whether exponentiations will overflow uses logarithms. The idea is based on these relationships:
a^b <= m <=> log(a^b) <= log(m) <=> b * log(a) <= log(m) <=> b <= log(m) / log(a)
For instance,
int a = 1024;
for (int b = 0; b < 10; ++b) {
if (b * std::log(a) < std::log(std::numeric_limits<long>::max())) {
long c = std::pow(a, b);
std::cout << c << '\n';
}
else
std::cout << "overflow\n";
}
This gives the idea. I hope this helps.
Unless it's particularly performance-critical, the suggestion would be to try it and see. If it overflows a double, std::pow will return HUGE_VAL. Hence something like:
double val = std::pow(a, b);
if(val != HUGE_VAL) {
...
} else {
mpz_t c;
//...
}
You can easily use the reverse functions in the test:
if ( std::log( DBL_MAX ) / std::log( a ) < b ) {
// std::pow( a, b ) will not overflow...
} else {
}
It might be just as good to just do the pow, and see if it
succeeds:
errno = 0;
double powab = std::pow( a, b );
if ( errno == 0 ) {
// std::pow succeeded (without overflow)
} else {
// some error (probably overflow) with std::pow.
}
You won't gain much time by just calculating std::log( a ).
(std::log( DBL_MAX ) is, of course, a constant, so only needs
to be calculated once.)
With a logarithm base 10, you can deduce that std:pow(a, b) has log(a^b) = b log a digits. You can then trivially see if it fits a double, which can fit values up to DBL_MAX.
However, this method performs additional computation than just computing a^b once. Measure a version with GMP first and see if checking for overflow actually provides any measurable and reproducible benefits.
EDIT: Ignore this, std::pow already returns an appropriate value in case an overflow occurs, so use that.