Search code examples
floating-pointprecision

How to get the smallest numberA that is N times another numberB, and bigger or equal numberC


I want to get the smallest number (floatA) that is N times a number(floatB), and this number must be bigger or equal to another number (floatC), for example

float_c = 20.0
float_b = 7.0
than number that is N times float_b is: 21, 28, 35 ...
so float_a is 21.0

some code like below might not work (I am not sure)

let tmp = float_c / float_b;
let tmp = tmp.ceil();
float_a = tmp * float_b;

/*
e.g: 
float_c = 21.0
float_b = 7.0;
let tmp = 21.0 /7.0;  // 3.00000000000001;
let tmp = tmp.ceil();   // 4.0
float_a = tmp * 7.0; //28, that's worng
*/

Will this code below work?

float_c = 21.0
float_b = 7.0;
let tmp = 21.0 / 7.0; // 3.00000000001
let tmp2 = tmp.ceil(); // 4.0
let float_a = tmp2 * float_b;
let float_backtest = float_a - float_b;

if (float_backtest - float_c).abs() < epsilon:
    return float_c
else:
    return float_a;



Solution

  • If c and b are positive, then this C code produces the least multiple of b that is greater than c:

    // If c <= b, b is the first multiple of b greater than or equal to c.
    if (c <= b)
        a = b;
    else
    {
        // Get the remainder of c modulo b.  This is exact by nature of fmod.
        double r = fmod(c, b);
    
        // If c is exactly a multiple of b, it is the desired result.
        if (r == 0)
            a = c;
    
        /* Otherwise, calculate the amount to add to c to make it a multiple,
           then add it. "b - r" is exact because r cannot have any bits lower
           in position value than b has (because b <= c) nor any higher
           (because r < b). The addition of c may be inexact, but then the
           desired result is not representable.
        */
        else
            a = b - r + c;
    }