根据每平方英寸压力(PSI)和兆帕斯卡(MPa),我有以下转换:
psi = MPa*1.45038;
我需要将转换后的最低值设为1 PSI。我正在寻找的一个例子是:
psi = ((long)MPa*145)/100
有没有使用float
或long
来优化内存和速度?我将在微控制器(PIC 18F2431)上实现这种转换。
答案 0 :(得分:1)
你应该用2的幂除以。根据{{1}}的类型及其最大值,您可以选择不同的分母来满足您的需求。如果乘法不会溢出,则无需转换为更宽的类型
如果MPa属于MPa
类型,则可以int16_t
(95052 /65536≈1.450378)
如果例如MPa不大于1024或2 10 那么你可以将它与2 21 相乘而不会溢出,因此你可以增加分子/分母以获得更多精度
psi = MPa*95052/(1 << 16);
修改强>
如果编译器的int类型是16位,那么95052将是psi = MPa*3041667/(1 << 21);
类型,因此MPa将被提升为long。如果您不想处理int32_t
并且不需要太高的精确度,那么您可以使用long
/ int
因为MPa不大于20所以你可以将它除以2048,这是2的最大幂,小于或等于2 16 / 20.
int16_t
请注意,psi = MPa*2970/(1 << 11);
和*
具有相同的优先级,因此它将从左到右进行评估,上面的等式将与
/
<强> EDIT2:强>
不幸的是,如果MPa的范围是[0,2000],那么你只能将它乘以32而不会溢出16位无符号整数。您可以获得的最接近的值是psi = (MPa*2970)/2048; // = MPa*1.4501953125)
,因此如果您需要更高的精度,除了使用46/32 = 1.4375
答案 1 :(得分:0)
计算最大N
,以便MPa*1.45038*2^N < 2^32
计算K = floor(1.45038*2^N)
一次
为psi = (MPa*K)>>N
MPa
的值
醇>
自0 <= MPa <= 2000
起,您必须选择N
,2000*1.45038*2^N < 2^32
:
2^N < 2^32/(2000*1.45038)
N < log(2^32/(2000*1.45038))
N < 20.497
N = 20
因此,K = floor(1.45038*2^N) = floor(1.45038*2^20) = 1520833
。
因此,对于MPa
的每个值,您都可以计算psi = (MPa*1520833)>>20
。
您需要确保MPa
为unsigned
(或相应地投射)。
使用此方法可以避免浮点运算。
为了更准确,您可以使用round
代替floor
,为您提供K = 1520834
。
在这种特定情况下,它会很好,因为2000*1520834
小于2^32
。
但是使用不同的最大值MPa
或不同的转化标量,它可能不会。
在任何情况下,psi
的每个值K
的结果差异都是可以忽略的。
const unsigned short lut[2001] = {...}
MPa
的每个值,请计算psi = lut[MPa]
而不是psi = (MPa*K)>>N
mul
操作,而不是shift
+ load
次操作但请注意,这在运行时性能方面是否更有效取决于几个因素,例如您在其中分配查找表的内存段的可访问性,处理器的体系结构手,运行时缓存启发式等。
因此,您需要在程序中应用一些分析,以确定哪种方法更好。