2

dB或分贝是用于显示对数比例的单位,特别是,我感兴趣的dB定义是X(dB)= 20log(x),其中x是“正常”值,X (dB) 是以 dB 为单位的值。当写了一个在mil之间转换的代码。和 mm,我注意到如果我使用直接方法,即乘以单位之间的比率,我会在相反的转换中得到小错误,即:to_mil [to_mm val_in_mil]不等于val_in_mil和与 mm 相同。图书馆单位已经解决了这个问题,因为它所做的转换没有那个计算错误。但是具体不提供(或者我没有找到)在库中将数字转换为 dB 的选项。

是否有另一个库/命令可以将数字转换为 dB 并将 dB 转换为数字而不会出现计算错误?

我做了一个使用直接数学转换的实验,我得到的是:

>> set a 0.005
0.005
>> set b [expr {20*log10($a)}]
-46.0205999133
>> expr {pow(10,($b/20))}
0.00499999999999
4

2 回答 2

4

这都是精确度的问题。我们经常倾向于忘记浮点数不是实数(在数学意义上的ℝ)。

你需要多少个十进制数字?

例如,如果您只需要 5 个十进制数字,则四舍五入 0.00499999999999 将为您提供 0.00500,这就是您想要的。

由于四舍五入 fp 数字不是一件容易的事,而且可能会产生更多的麻烦,您可能只需更改确定两个数字是否相等的方式:

 >> set a 0.005
 0.005
 >> set b [expr {20*log10($a)}]
 -46.0205999133
 >> set c [expr {pow(10,($b/20))}]
 0.00499999999999
 >> expr {abs($a - $c) < 1E-10}
 1
 >> expr {abs($a - $c) < 1E-20}
 0
 >> expr {$a - $c}
 8.673617379884035e-19

您的示例中的数字可以被视为“等于”错误或 10 -18。请注意,这只是一个粗略的估计,而不是完整的解决方案。

如果您真的在处理对数值误差传播敏感的问题,您可能会更深入地研究“数值分析”。文章What Every Computer Scientist Should Know About Floating-Point Arithmetic,或者更好的是,这个站点: http: //floating-point-gui.de可能是一个开始。

如果您需要更高的精度,则应放弃“本机”要求。

您可以使用 tcllib 提供的 BigFloat ( http://tcllib.sourceforge.net/doc/bigfloat.html,甚至可以通过 ffidl ( http://elf.org/ffidl ) 使用 GMP (GNU 多精度算术库)。已经为它定义了一个接口:gmp.tcl

于 2013-04-14T08:29:30.717 回答
1

使用存储浮点数的方式,每个 log10(...) 不能正好对应一个 pow(10, ...)。所以你失去了精度,就像整数除法 89/7 和 88/7 都是 12。

当您将一个值转换为浮点格式时,您应该忘记知道它的精确值的能力,除非您也保留旧的精确值。如果您想要精确的 1/200,请将其存储为整数 1 和整数 200。如果您想要精确的 1/200 的十对数,请将其存储为 1、200 和十对数已完成的信息它。

您可以用 2 的平方根的前 x 个十进制数字填充整个内存,但它仍然不是您存储的 2 的平方根。

于 2013-04-14T12:49:01.387 回答