dB或decibel是一个单位,用于显示对数刻度的比率,特别是,我感兴趣的dB的定义是X(dB)= 20log(x)其中x是“正常”值,X(dB)是以dB为单位的值。当写一个代码在mil之间转换。 mm,我注意到如果我使用直接方法,即乘以单位之间的比率,我在相反的转换上得到小错误,即:to_mil [to_mm val_in_mil]
不等于val_in_mil
并且与mm相同。库units解决了这个问题,因为它所做的转换没有计算错误。但具体没有提供(或者我没有找到)在库中将数字转换为dB的选项。
是否有另一个库/命令可以将数字转换为dB和dB,而不会产生计算错误?
我做了一个使用直接数学转换的实验,我得到的是:
>> set a 0.005
0.005
>> set b [expr {20*log10($a)}]
-46.0205999133
>> expr {pow(10,($b/20))}
0.00499999999999
答案 0 :(得分: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(http://tcllib.sourceforge.net/doc/bigfloat.html提供的BigFloat,甚至可以通过ffidl(http://elf.org/ffidl)使用GMP(GNU多精度算术库)。已经为它定义了一个接口:{{3 }}
答案 1 :(得分:1)
通过存储浮点数的方式,每个log10(...)不能完全对应一个pow(10,...)。所以你失去了精度,就像整数分区89/7和88/7都是12。
当你将一个值放入浮点格式时,你应该忘记了再次知道的确切值的能力,除非你保留旧的,精确的值。如果你想要1/200,则将它存储为整数1和整数200.如果你想要1/200的十对数,则将其存储为1,200和十对数已完成的信息它
你可以用2的平方根的前x个十进制数填充你的整个记忆,但它仍然不是你存储的2的平方根。