我调用vrndscalepd
来舍入ZMM寄存器。要舍入的寄存器是:
{3.9304247359239284, 0.85804618270500566, 1.899940908279022,
1.5554455222287524, 9.1150061014624413, 9.3562881423859334,
1.3206387781690712, 9.0367010342260201}
字符串
我想把这些都四舍五入到小数点后两位,但我尝试过的四舍五入模式代码都没有做到这一点:
vrndscalepd zmm9{k1}{z},zmm8,32 ; 00100000
{4, 0.75, 2, 1.5, 9, 9.25, 1.25, 9}
vrndscalepd zmm9{k1}{z},zmm8,33 ; 00100001
{3.75, 0.75, 1.75, 1.5, 9, 9.25, 1.25, 9}
vrndscalepd zmm9{k1}{z},zmm8,34 ; 00100010
{4, 1, 2, 1.75, 9.25, 9.5, 1.5, 9.25}
vrndscalepd zmm9{k1}{z},zmm8,35 ; 00100011
{3.75, 0.75, 1.75, 1.5, 9, 9.25, 1.25, 9}
vrndscalepd zmm9{k1}{z},zmm8,41 ; 00110001
{3.75, 0.75, 1.75, 1.5, 9, 9.25, 1.25, 9}
vrndscalepd zmm9{k1}{z},zmm8,42 ; 00110010
{4, 1, 2, 1.75, 9.25, 9.5, 1.5, 9.25}
型
这些都没有达到我的要求。在AVX512上,我是否错过了另一种舍入模式,该模式将舍入到小数点后两位,而不会舍入到0.25的最接近偶数倍?是否有另一条指令可以使用ZMM寄存器实现我的要求?
1条答案
按热度按时间b4qexyjb1#
不,AVX-512使用二进制浮点,而不是十进制。
(https://en.wikipedia.org/wiki/Double-precision_floating-point_format)的最大值
3.93
不能精确地表示为float或double,因此任何指令序列都不可能创建表示它的位模式。当然,你可以做一些事情来得到一个接近的值,比如
3.9300000667572021484375f
,但这并不像vrndscaleps/pd
那样将尾数的一些低位清零那么简单。这必然会产生一个可以表示为分母为2的幂的分数的值(因为所有FP值都是这样的。)一个“更圆”的二进制FP值将有一个更小的分母;在基数点后2位,分母将是4,因此.0
,.25
,.5
或.75
是唯一的可能性。四舍五入到2位小数的正常方法是乘以100.0,四舍五入到最接近的整数,乘以
1.0/100
。我不知道是否有更有效/更聪明的方法。(注意1.0/100
不能精确表示,所以除以100.0
可能更精确。)