将16位整数转换为0..100

时间:2017-05-28 00:06:44

标签: math

我有一个系统采用/给出音量(如在音频放大器中)作为16位无符号整数。我有另一个系统,它接受/给出0到100之间的整数。

0为0 100是65536

转换成数字的数学是什么?例如。在C#。

2 个答案:

答案 0 :(得分:0)

除以655.36与乘以100然后除以65536相同,这可以纯粹用整数运算来完成:

int scaled = input * 100 >> 16;

然而,由于分裂/右移中隐含的截断,因此向下偏向(因此不会导致100)。您可以通过添加0.5的偏差来均匀地使其圆整,

int temp = input * 100;
temp += 0x8000; // 0x8000 = 0.5 in Q16
int scaled = temp >> 16;

这里,0xfeb9及以上将导致100.如果因为100是独占绑定而不应该发生,那么你当然可以乘以99而不是。

另一种方法可以使用相同的原则来完成,

int scaled = ((input << 16) - 50) / 100;

这确保了100 - > 65535,65536不是16位数,所以应该避免使用它。

很大程度上类似的事情可以做得更短,但有额外的乘法,

int scaled = input * 65535 / 100;

它的结果分布有点不同,但它并没有太大区别。

答案 1 :(得分:-1)

使用Vala,它非常类似于C#(一种非常粗略和简单的方法):

public static int convert_from_unsigned_int_to_percentage (uint16 val) {
    return (int) ((val / 65535.0) * 100);
}

public static uint16 convert_from_percentage_to_unsigned_int (int val) {
    return (uint16) ((val / 100.0) * 65535);
}

int main (string[] args) {
    print ("test1 65535 -> ? = %d\n", convert_from_unsigned_int_to_percentage (65535));
    print ("test1 32500 -> ? = %d\n", convert_from_unsigned_int_to_percentage (32500));
    print ("test1 100%% -> ? = %d\n", convert_from_percentage_to_unsigned_int (100));
    print ("test1 50%% -> ? = %d\n", convert_from_percentage_to_unsigned_int (50));

    return 0;
} 

输出:

./volume 
test1 65535 -> ? = 100
test1 32500 -> ? = 49
test1 100% -> ? = 65535
test1 50% -> ? = 32767