如何将数字舍入到最接近的10的幂次方?

4

我甚至不能找到与此相关的搜索关键字。 请看一下这段代码:

float inputValue = getInputValue();
float resultValue;

if (inputValue < 0.1f) {
    resultValue = 0.01f;
}
else if (inputValue < 1.0f) {
    resultValue = 0.1f;
}
else if (inputValue < 10.0f) {
    resultValue = 1.0f;
}
else {
    resultValue = 10.0f;
}

等等,必须有更优雅的方法来解决这个问题。我想这个解决方案很容易,但是我已经花费了两个小时去寻找一种方法,并阅读了关于round,ceil,floor等内容,但我无法找到。

有人有什么想法吗?


你想要将数字四舍五入到一位有效数字吗? - Tommy
尝试使用log10(),并优先使用double - pmg
而要进行四舍五入,只需使用 pow(10.0, ceil(log10(value))) - 没有必要编辑答案,但我想添加一条评论。 - FreelanceConsultant
4个回答

6
powf(10.0f, floorf(log10f(value)))

编辑过了,我只是发布伪代码作为一个想法。现在应该在C++中正确编译(我忘记了,在math.h中C++实际上确实有基于10的对数)。 - Spook
完美运作。没有我想象的那么简单,我怀疑我自己可能不会找到:) 谢谢! - user1840267
一些功劳归功于@Tommy - 我忘记了math.h中的floorflog10f函数。但无论如何,我很高兴能够帮助:) - Spook
1
如何将数字舍入到最接近的10的幂次方? - pat
1
对于边缘情况,代码可能在大值(如value=99999997952)时失败,返回的是99,999,997,952而不是10,000,000,000。这两个值都可以精确表示为“float”。接近各种负10次幂的值也可能失败。例如,使用“float f = 9.99999975e-03”,此代码返回“9.99999975e-03”而不是接近“1.0e-03”的值。使用“double”也有相同的问题,尽管更少见且具有不同的值。 - chux - Reinstate Monica
显示剩余4条评论

2
我相信有一种更简单的方法,不需要从基本原理开始工作,但是怎么样:

我确信有一种更简单的方法,不需要试图从第一原则开始工作,但是怎么样:

float inputValue = getInputValue();

float log10 = floorf(log10f(inputValue));
float modulo = powf(10.0f, log10);
inputValue -= fmodf(inputValue, modulo);

编辑:实际上,我认为您可能希望将230四舍五入为200,0.73四舍五入为0.7等,因此这可能不是答案。但我仍然保留回答,因为它可能仍有一定帮助。


1
你的代码没有达到你预期的结果。对于任何小于100(包括0.001)的值,resultValue都将被设为10。你需要按相反的顺序检查。
我会先为这个函数编写规范:对于什么输入值,您期望什么输出值?对于输入1.01e17,您是否期望1.0e17?如果输入为0或-1,会发生什么?

0
这是一个 BigInteger 版本。 我需要下一个(而不是最接近的)10 的幂,但你可以看到这个想法:
import java.math.BigInteger;

class A {
    public static void main(String[]args) {
        System.out.println("hi");
    for (long v : new long[] {0,1,2,9,10,11,99,100,101,12345678,123456789012345678L,1234567890123456789L}) {
            System.out.println(""+v+" ==> "+nextPowerOf10(v));
        }
    }
    static long nextPowerOf10(long v) {
        return BigInteger.TEN.pow((int)Math.max(0,1+Math.floor(Math.log10(v)))).longValue();
    }
}

如果你想让它在10的幂次方上表现不同,可以尝试调整上面的1+Math.floor(0/1、floor/ceil/round)代码。顺便问一句,OP所说的“nearest”是指线性尺度还是对数尺度?是指最接近的大于还是最接近的小于?

>java A
hi
0 ==> 1
1 ==> 10
2 ==> 10
9 ==> 10
10 ==> 100
11 ==> 100
99 ==> 100
100 ==> 1000
101 ==> 1000
12345678 ==> 100000000
123456789012345678 ==> 1000000000000000000
1234567890123456789 ==> -8446744073709551616

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接