Optimization PIC 18F2431上的单位转换

Optimization PIC 18F2431上的单位转换,optimization,floating-point,long-integer,pic,Optimization,Floating Point,Long Integer,Pic,给定每平方英寸(PSI)和兆帕(MPa)的压力,我有以下转换: 我需要转换后的最低值可能是1磅/平方英寸。我正在寻找的一个例子是: psi = ((long)MPa*145)/100 是否可以通过不使用float或long来优化内存和速度?我将在微控制器(PIC 18F2431)上实现这种转换。你应该用2的幂除,这比用任何其他值除要便宜得多。如果类型不能为负,则使用无符号类型。根据MPa的类型及其最大值,您可以根据需要选择不同的分母。如果乘法不会溢出,则无需强制转换为更宽的类型 例如,如果MP

给定每平方英寸(PSI)和兆帕(MPa)的压力,我有以下转换:

我需要转换后的最低值可能是1磅/平方英寸。我正在寻找的一个例子是:

psi = ((long)MPa*145)/100

是否可以通过不使用
float
long
来优化内存和速度?我将在微控制器(PIC 18F2431)上实现这种转换。

你应该用2的幂除,这比用任何其他值除要便宜得多。如果类型不能为负,则使用无符号类型。根据MPa的类型及其最大值,您可以根据需要选择不同的分母。如果乘法不会溢出,则无需强制转换为更宽的类型

例如,如果
MPa
属于
uint16\u t
类型,则可以执行
psi=MPa*95052/(1UL
  • 计算最大的
    N
    ,使
    MPa*1.45038*2^N<2^32

  • 计算
    K=floor(1.45038*2^N)
    的常量值一次

  • 对于
    MPa


  • 020以来

    您需要确保
    MPa
    unsigned
    (或相应地强制转换)

    使用此方法可以避免浮点操作


    为了获得更好的准确度,您可以使用
    圆形
    而不是
    地板
    ,使您获得
    K=1520834

    在这种特定的情况下,它的结果很好,因为
    2000*1520834
    小于
    2^32

    但如果使用不同的最大值
    MPa
    或不同的转换标量,则可能不会

    在任何情况下,对于
    K
    的每个值,
    psi
    的结果差异都是可以忽略的


    顺便说一句,如果您不介意额外的内存,那么您可以使用查找表:

    • 添加预先计算的全局变量
      const unsigned short lut[2001]={…}
    • 对于
      MPa
      的每个值,计算
      psi=lut[MPa]
      而不是
      psi=(MPa*K)>>N
    • 因此,您的程序将执行
      load
      操作,而不是
      mul
      +
      shift
      操作
    但是,请注意,就运行时性能而言,这是否更有效取决于几个因素,例如分配查找表的内存段的可访问性、手头处理器的体系结构、运行时缓存启发法等


    因此,您需要在程序上应用一些评测,以决定哪种方法更好。

    MPa的最小值和最大值是多少?
    MPa
    在[0,20]范围内?值的范围是0~2000MPa。很抱歉,它是0~2000MPa[02000]而不是[0,20]。那么,您可以使用
    psi=(MPa*1520833)>>20
    psi=((无符号)MPa*1520833)>>20
    如果
    MPa
    不是
    无符号的
    。请看我下面的答案。请澄清1)MPa*95092将溢出一个16位整数。否则2)95052/65536将给出1,而不是整数除法的1.45。@EmbSysDev,所以不必担心。在16位int环境中,95052将具有适合它的任何类型(在本例中很可能是长的)。对于后一个答案,将首先执行乘法,而不是除法,因此结果不是1是的,我需要使用0~2000,对混淆感到遗憾。目前我使用浮点运算,并获得正确的结果。它不是一个非常快的应用程序,因此性能足够好。我只是想知道是否有更好的方法来执行。是的。使用long仍然比float快得多,并且消耗更少的代码空间,因为您不需要包含float库
    psi = ((long)MPa*145)/100
    
    psi = MPa*3041667/(1UL << 21);
    
    psi = MPa*2970/(1U << 11);
    
    psi = (MPa*2970)/2048; // = MPa*1.4501953125)