Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print a double value that is just less than another double value?

Actually I am working on range expression in c++. So what I want is if I have any expression like

x<1

Then my

double getMax(...);

should return a double value that is just before 1.000 (double precision) on a number line.

I tried doing this

double getMax(double& a)
{
    return (a-numeric_limits<double>::min());
}

But I am still getting same value as a in return statement.

I think C++ is converting it to nearest double in cout statement.

int main()
{
    double a = 32;
    cout<<scientific<<getMax(a)<<endl;
    return 0;
}

output:

3.200000e+001
like image 865
Apoorva sahay Avatar asked Feb 26 '13 07:02

Apoorva sahay


1 Answers

First of all, you need to ensure that you actually print sufficiently many digits to ensure all representable values of double are displayed. You can do this as follows (make sure you #include <iomanip> for this):

    std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl;

Secondly, numeric_limits<>::min is not appropriate for this. If your starting value is 1.0, you can use numeric_limits<double>::epsilon, which is the smallest difference from 1.0 that is representable.

However, in your code example, the starting value is 32. Epsilon does not necessarily work for that. Calculating the right epsilon in this case is difficult.

However, if you can use C++11(*), there is a function in the cmath header that does what you need std::nextafter:

#include <iostream>
#include <limits>
#include <iomanip>
#include <cmath>

double getMax(double a)
{
  return std::nextafter(a,std::numeric_limits<double>::lowest());
}

int main()
{
    double a = 32;
    std::cout << std::scientific
              << std::setprecision(std::numeric_limits<double>::max_digits10)
              << getMax(a)
              << std::endl;
    return 0;
}

I've also put it on liveworkspace.

To explain:

double nextafter(double from, double to);

returns the next representable value of from in the direction of to. So I specified std::numeric_limits<double>::lowest() in my call to ensure you get the next representable value less than the argument.

(*)See Tony D's comment below. You may have access to nextafter() without C++11.

like image 119
jogojapan Avatar answered Oct 25 '22 16:10

jogojapan