Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 四舍五入到最近的尼斯数_Java_Rounding - Fatal编程技术网

Java 四舍五入到最近的尼斯数

Java 四舍五入到最近的尼斯数,java,rounding,Java,Rounding,我正在编写一个应用程序,它要求将标签舍入到最近的“nice”数字。我将在下面放一些代码来演示这一点,但我的问题是,我使用了一系列其他ifs来查找这个数字,但我无法确定上限,因此这不是一个好的策略。是否有任何已知的算法或资源可以帮助我 if (diff <= 1) { roundAmount = 0.2; } else if (diff <= 5) { roundAmount = 1; } else if (diff <=

我正在编写一个应用程序,它要求将标签舍入到最近的“nice”数字。我将在下面放一些代码来演示这一点,但我的问题是,我使用了一系列其他ifs来查找这个数字,但我无法确定上限,因此这不是一个好的策略。是否有任何已知的算法或资源可以帮助我

    if (diff <= 1) {
        roundAmount = 0.2;
    } else if (diff <= 5) {
        roundAmount = 1;
    } else if (diff <= 10) {
        roundAmount = 2;
    } else if (diff <= 25) {
        roundAmount = 5;
    } else if (diff <= 50) {
        roundAmount = 10;
    } else if (diff <= 100) {
        roundAmount = 20;
    } else if (diff <= 250) {
        roundAmount = 50;
    } else if (diff <= 500) {
        roundAmount = 100;
    } else if (diff <= 1000){
        roundAmount = 200;
    } etc...

if(diff在执行“尼斯数字”搜索之前,您可以使用
Math.log10
对所有值进行规范化,如下所示:

[Edit]我刚刚意识到您使用的是Java而不是C#,所以我对代码进行了一些修改。我没有编译器来测试它,但您应该了解一下大致思路:

static double getNicerNumber(double val)
{
    // get the first larger power of 10
    var nice = Math.pow(10, Math.ceiling(Math.log10(val)));

    // scale the power to a "nice enough" value
    if (val < 0.25 * nice)
        nice = 0.25 * nice;
    else if (val < 0.5 * nice)
        nice = 0.5 * nice;

    return nice;
}

// test program:
static void main(string[] args)
{
    double[] values = 
    {
        0.1, 0.2, 0.7,
        1, 2, 9,
        25, 58, 99,
        158, 267, 832
    };

    for (var val : values)
        System.out.printf("$%.2f --> $%.2f%n", val, getNicerNumber(val));
}
静态双getNicerNumber(双val)
{
//获得第一个较大的10次方幂
var nice=Math.pow(10,Math.天花板(Math.log10(val));
//将功率缩放到“足够好”的值
如果(val<0.25*nice)
尼斯=0.25*尼斯;
否则如果(val<0.5*nice)
尼斯=0.5*尼斯;
回报美好;
}
//测试程序:
静态void main(字符串[]参数)
{
双[]值=
{
0.1, 0.2, 0.7,
1, 2, 9,
25, 58, 99,
158, 267, 832
};
用于(var val:值)
System.out.printf(“$%.2f-->$%.2f%n”,val,getNicerNumber(val));
}
这将打印如下内容:

0,1 --> 0,1 0,2 --> 0,25 0,7 --> 1 1 --> 1 2 --> 2,5 9 --> 10 25 --> 50 58 --> 100 99 --> 100 158 --> 250 267 --> 500 832 --> 1000 0,1 --> 0,1 0,2 --> 0,25 0,7 --> 1 1 --> 1 2 --> 2,5 9 --> 10 25 --> 50 58 --> 100 99 --> 100 158 --> 250 267 --> 500
832-->1000我提出了这个相当粗糙的解决方案,它返回了我刚才测试的所有情况下的正确值:

public static double foo(long value) {
    for (double i = 0.2; true; i *= 5) {
        if (i >= value) {
            return i / 5;
        }
    }
}

尽管我必须承认,格罗发布的数学解会更漂亮。

我更喜欢下面的方法,因为它是267到275轮,而不是500轮。它基本上是四舍五入到第一个数字,然后是10次方的四分之一

static double round_pretty(double val) {
    var fraction = 1;
    var log = Math.floor(Math.log10(val));

    // This keeps from adding digits after the decimal
    if(log > 1) {
        fraction = 4;
    }

    return Math.round(val * fraction * Math.pow(10, -log)) 
        / fraction / Math.pow(10, -log);
}
结果如下:

0.01 -> 0.01
0.025 -> 0.03    (Groo's does 0.025)
0.1 -> 0.1
0.2 -> 0.2       (Groo's does 0.25)
0.49 -> 0.5
0.5 -> 0.5       (Groo's does 1)
0.51 -> 0.5      (Groo's does 1)
0.7 -> 0.7       (Groo's does 1)
1 -> 1
2 -> 2           (Groo's does 2.5)
9 -> 9
23.07 -> 20
25 -> 30
49 -> 50
50 -> 50         (Groo's does 100 here)
58 -> 60
94 -> 90
95 -> 100
99 -> 100
100 -> 100
109 -> 100       (Groo's does 250 here)
158 -> 150
249 -> 250
267 -> 275
832 -> 825
1234567 -> 1250000
1499999 -> 1500000
1625000 -> 1750000

你确定}else if(diff)只有在你能为“nice”舍入定义具体规则的情况下,你才能应用算法。你脑子里有这样的规则吗?很难从你发布的代码中分辨出来。舍入是如何工作的,即如何定义那些“nice”数字?例如:51将舍入为20(这是一个不错的数字吗?)而50四舍五入为10?这应该作为评论发布,因为它不能回答问题。@Jonathan:虽然我同意你的观点,但这应该是一个评论,因为它不是问题的真正答案。是的,这太完美了。我不知道你用的是C#而不是半伪代码!