圆形到一些基本浮动单元的偶数(或不均匀)倍数

时间:2018-01-19 10:12:10

标签: java rounding

如何舍入到一些基本浮点单位的倍数(比如0.0005f

float example_input = 2.718281828459f;

float unit = 0.0005f;

这样output的格式为2*n*unitn为自然数,output尽可能接近example_input < / p>

另外,对于不均匀的倍数如何做到这一点?

编辑:这是我到目前为止所提出的,但它错了:

float roundToEvenMultiple(float input, float unit){
    float output = input - (input % (2*unit));
    return output;
}

float roundToUnevenMultiple(float input, float unit){
    float output = input - (input % (3*unit));
    return output;
}

编辑2:

这是对这个问题的又一次尝试,但不适用于负数,而且似乎非常低效。

  float roundToEvenMultiple(float input, float unit){

    float result = 0;
    while (result < input){
      result += 2*unit;
    }
    return result;
  }

  float roundToUnevenMultiple(float input, float unit){

    float result = 0;
    while (result < input){
      result += 3*unit;
    }
    return result;
  }

编辑3:

用于

example_input = 2.718281828459f;

unit = 0.0005f;

应输出偶数多舍入程序:2.718 应该输出不均匀的多舍入程序:2.7185

2 个答案:

答案 0 :(得分:1)

设k为输入x中的单位数。 然后,如果k是奇数,则其余小于一个单位,因此k *单位是结果。 如果k是偶数,则数字在奇数k-1的上半部分,因此(k + 1)*单位是结果。

float roundToUnevenMultiple(float x, float unit) {
    int k = (int) (x / unit);
    if (k % 2 == 0) {
        ++k; // Upper half
    }
    return k * unit;
}

甚至多个案例已经很简单了。但可以这样做:

float roundToEvenMultiple(float x, float unit) {
    int k = (int) (x / unit);
    if (k % 2 == 1) {
        ++k; // Upper half
    }
    return k * unit;
}

对于大k,单位中的近似误差将被放大。所以做得更准确:

float roundToUnevenMultiple(float x, float unit) {
    float remainder = x % unit;
    float y = x - remainder;
    int k = (int) (x / unit);
    if (k % 2 == 0) {
        y += unit;
    }
    return y;
}

float roundToEvenMultiple(float x, float unit) {
    float remainder = x % unit;
    float y = x - remainder;
    int k = (int) (x / unit);
    if (k % 2 == 1) {
        y += unit;
    }
    return y;
}

使用double肯定会更好,更常见,主要做法。

答案 1 :(得分:0)

尝试以下方法:

public static void main(String[] args) {
  System.out.println(round(2.718281828459f, 0.00002f));
}

static float round(float num, float granularity) {
  return Math.round(num * (1.0f/granularity)) * granularity)
}

输出为2.71828

但是,请注意,如果您在计算中使用它之前截断值,那么它会受到累积误差的影响。如果保留原始精度,然后使用System.out.format()将其显示给用户,您将获得更好的结果。