8

I have some troubles explaining clearly but it's rather simple..

I have a double named value in my C++ program and I want to Floor it if it's a positive value and Ceil if it's a negative value, the precision is given by an external variable.

An example:

precision is of 1000 value is 0.2659 so approximated value is 0.265
value is -0.2659 so approximated value is -0.265

I have wrote a simple code but I was wondering if there was a more simple or/and way to do it.

Here what I have so far:

void NodeImpl::approximation(double& value, const double& precision)
{
    if (value > 0.0)
    {
        value = std::floor(value * precision);
    }
    else
    {
        value = std::ceil(value * precision);
    }
    value /= precision;
}

I have wrote a simple code but I was wondering if there was a more simple or/and way to do it.

tony497
  • 360
  • 1
  • 3
  • 15
  • 2
    Looks ok to me but do note that the final `value` may have joke digits after the decimal 15th significant figure, e.g. `0.265` is actually `0.26500000000000001332267629550187848508358001708984375`. Out of interest, why are you passing `precision` by `const` reference? – Bathsheba Oct 30 '18 at 11:03
  • i only know a more compilcated way: ceil the absolute value and then multiply with the original sign. Consider to post questions asking for review of working (!) code on https://codereview.stackexchange.com/ – 463035818_is_not_an_ai Oct 30 '18 at 11:03
  • 2
    be warned that your intended operation cannot be performed *exactly*: the number `0.265`, for example, has no finite floating-point representation, so you must not rely in your code on any exactness. – Walter Oct 30 '18 at 11:23
  • @LightnessRacesinOrbit: It's the term my professor used at university, honest! (And respect to the smiley face in the comment.) – Bathsheba Oct 30 '18 at 11:35
  • @Bathsheba Recently discovered the emoji key combo on OSX and I'll be darned if i'm not going to make the most of it – Lightness Races in Orbit Oct 30 '18 at 12:29
  • 1
    @LightnessRacesinOrbit: Oh I'm going to enjoy this. – Bathsheba Oct 30 '18 at 12:36
  • @Someprogrammerdude: I'm using reference for both of the arguments for the efficiency. This way I don't copy my arguments in local variables, even if I agree it doesn't really matters here for the size of the arguments. And the same for the returning value. Why would you do it differently ? – tony497 Oct 30 '18 at 12:56
  • 3
    Considering that references usually is implemented as pointers, you're still passing 64 bits of data, which also happens to happens to be the common size for the `double` type. In short, there's nothing gained. Generally, for primitive types (`int`, `double`, etc.) ***don't*** pass by reference unless you need to modify the value inside the function. – Some programmer dude Oct 30 '18 at 13:00
  • 1
    ^ It's easier to follow and potentially easier to optimise. When you have bigger types the gain of avoiding a copy is worth it, but otherwise you're just making things "more difficult/complex" for no gain. – Lightness Races in Orbit Oct 30 '18 at 13:21

1 Answers1

9

You can use std::trunc:

return std::trunc(value * precision) / precision;
ash108
  • 1,763
  • 1
  • 17
  • 21
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • @user463035818 it return nearest integer not greater in magnitude to the argument i.e. rounds towards zero. – eerorika Oct 30 '18 at 11:13