我目前正在尝试弄清楚如何以定点表示形式将两个数字相乘。
假设我的数字表示如下:
[SIGN][2^0].[2^-1][2^-2]..[2^-14]
Run Code Online (Sandbox Code Playgroud)
就我而言,数字10.01000000000000 = -0.25.
例如我会怎么做0.25x0.25等等-0.25x0.25?
希望您能帮忙!
目前,我正在使用一个小型查找表和线性插值,它非常快且足够准确(最大误差小于 0.001)。然而我想知道是否有一个更快的近似值。
由于指数的整数部分可以通过位移来提取和计算,因此近似值只需要在 [-1,1] 范围内工作我尝试找到切比雪夫多项式,但对于低多项式无法达到良好的精度命令。我猜我可以忍受 0.01 左右的最大误差,但我没有接近这个数字。高阶多项式不是一种选择,因为它们比我当前的基于查找表的解决方案效率低得多。
编译失败并显示以下 F6 声明:
type F3 is delta 2.0**(-4) range 0.0 .. ((2.0**8)-1.0)*2.0**(-4); -- byte 16#f.f#;
for f3'size use 8;
type F4 is delta 2.0**(-8) range 0.0 .. ((2.0**16)-1.0)*2.0**(-8); -- word 16#ff.ff#
for f4'size use 16;
type F5 is delta 2.0**(-16) range 0.0 .. ((2.0**32)-1.0)*2.0**(-16); -- dword 16#ffff.ffff#
for f5'size use 32;
type F6 is delta 2.0**(-32) range 0.0 .. ((2.0**64)-1.0)*2.0**(-32); -- ldword 16#ffff_ffff.ffff_ffff#
for f6'size use 32;
Run Code Online (Sandbox Code Playgroud)
在 linux64/v8.0.3 和 learn.adacore.com 上同样失败。
编辑错误消息是“类型“f6”所需的大小 (65) 太大,允许的最大值为 64”
编辑添加'尺寸说明/预期的十六进制上限
编辑 …
我为 iPhone 编写了一个小型软件合成器。为了进一步调整性能,我使用 Shark 测量了我的应用程序,发现我在转换方面损失了大量时间float/SInt16。
因此,我重写了一些部分,通过预先计算返回“即用型”SInt16样本的查找表来绕过转换。到目前为止效果很好。
目前,我正在尝试重写一些过滤器和我的 ADSR 包络实现,以仅使用整数算术,但我可以使用一些关于如何在没有浮点数的情况下执行乘法/除法的技巧。
我的目标是iPhone 规范格式:
在不使用浮子的情况下将振幅应用于最终样本的好方法是什么?
编辑:
到目前为止我唯一想到的是,我可以通过右移当前样本来除以 2 的幂。
inBuffer[frame] = wavetable[i % cycleLengthInSamples] >> 4;
Run Code Online (Sandbox Code Playgroud)
但我想不出任何优雅的方法来创建平滑的 ADSR 信封。
Edit2:
感谢您的所有精彩回答!
我目前的做法:
SInt16范围SInt32)这似乎有效:)
iphone signal-processing fixed-point core-audio integer-division
我想为没有浮点单元的ARM设备优化我的C++代码.我的大多数函数都使用浮点数,我正在考虑将它们更改为定点.
在ARM设备的情况下是否有真正的好处,或者编译器是否足够智能自己做到这一点?
例如,这对ARM设备更有效
//unsigned char const* input
unsigned int a, b;
a= *input++ << 12;
b= *input++ << 12;
a*=1024; //0.25 shifted 12 bits
b*=1024; //0.25 shifted 12 bits
*output++ = (a+b) >> 24;
Run Code Online (Sandbox Code Playgroud)
比做
float a,b;
a= *input++;
b= *input++;
a=a/4;
b=a/4;
*output++ = a+b;
Run Code Online (Sandbox Code Playgroud) 我试图在Python 3.2中编写一个加密短语然后解密的方法.问题是数字是如此之大,以至于当Python对它们进行数学运算时,它会立即将其转换为科学记数法.由于我的代码要求所有数字都能用于科学记数法,所以这没用.
我有的是:
coded = ((eval(input(':'))+1213633288469888484)/2)+1042
Run Code Online (Sandbox Code Playgroud)
基本上,我只是从用户那里得到一个数字并做一些数学计算.
我尝试format()了其他一些东西,但我无法让它们工作.
编辑:我只使用整数.
python format floating-point scientific-notation fixed-point
我试图在VHDL中使用'浮点和定点包'作为我的滤波器设计的一部分.我使用Altera Quartus II作为开发环境.我从以下网站下载了文件包:http://www.vhdl.org/fphdl/,现可在http://web.archive.org/web/20160305202256/http://www.vhdl.org/fphdl上找到/
在他们的用户指南中,提到了以下内容:
'fixed_float_types_c.vhdl', 'fixed_pkg_c.vhdl' and 'float_pkg_c.vhdl'
should be compiled into a library called "ieee_proposed".
Run Code Online (Sandbox Code Playgroud)
但是,我并不确切知道如何使用Altera Quartus II工具将提到的*.vhdl文件编译到库中.
任何提示将不胜感激.
我做了一个函数来计算atan2(y,x)的定点近似.问题在于运行整个函数所需的~83个循环,70个循环(在AMD FX-6100上使用gcc 4.9.1 mingw-w64 -O3进行编译)完全由一个简单的64位整数除法完成!遗憾的是,该分裂的任何条款都不变.我能加速分裂吗?有什么方法可以删除它吗?
我想我需要这个除法,因为我用1D查找表近似atan2(y,x)我需要将x,y表示的点的距离标准化为单位圆或单位正方形(我选择了一个单位')菱形'是一个旋转45°的单位正方形,在正象限上提供非常均匀的精度).所以除法找到(| y | - | x |)/(| y | + | x |).注意,除数是32位,而分子是32位数,右移29位,因此除法的结果有29个小数位.同样使用浮点除法不是一个选项,因为此函数不需要使用浮点运算.
有任何想法吗?我想不出有什么可以改善这一点(我无法弄清楚为什么只需要一个师就需要70个周期).这是完整的参考功能:
int32_t fpatan2(int32_t y, int32_t x) // does the equivalent of atan2(y, x)/2pi, y and x are integers, not fixed point
{
#include "fpatan.h" // includes the atan LUT as generated by tablegen.exe, the entry bit precision (prec), LUT size power (lutsp) and how many max bits |b-a| takes (abdp)
const uint32_t outfmt = 32; // final output format in s0.outfmt
const …Run Code Online (Sandbox Code Playgroud) 我需要乘两个符号的64位整数a和b在一起,然后转移(128位)的结果到一个符号的64位整数.最快的方法是什么?
我的64位整数实际上代表具有fmt小数位的定点数.fmt被选择为使得a * b >> fmt不应溢出,例如abs(a) < 64<<fmt和abs(b) < 2<<fmt与fmt==56永远不会溢出64位作为最终结果将是< 128<<fmt,因此适合在一个Int64.
我想这样做的原因是为了快速准确地评估((((c5*x + c4)*x + c3)*x + c2)*x + c1)*x + c0定点格式的形式的五次多项式,每个数字都是带有fmt小数位的带符号的64位定点数.我正在寻找实现这一目标的最有效方法.
我需要根据非常数因子将值从一个单位转换为另一个单位.输入值范围为0到1073676289,范围值范围为0到1155625.转换可以这样描述:
output = input * (range / 1073676289)
Run Code Online (Sandbox Code Playgroud)
我自己的初始定点实现感觉有点笨拙:
// Input values (examples)
unsigned int input = 536838144; // min 0, max 1073676289
unsigned int range = 1155625; // min 0, max 1155625
// Conversion
unsigned int tmp = (input >> 16) * ((range) >> 3u);
unsigned int output = (tmp / ((1073676289) >> 16u)) << 3u;
Run Code Online (Sandbox Code Playgroud)
我的代码可以改进为更简单或更准确吗?
fixed-point ×10
c ×3
optimization ×2
ada ×1
arm ×1
c++ ×1
core-audio ×1
format ×1
gnat ×1
int128 ×1
integer ×1
intel-fpga ×1
iphone ×1
python ×1
quartus ×1
vhdl ×1