【问题标题】:sprintf in Matlab: use compact representation, but always include trailing zeroMatlab 中的 sprintf:使用紧凑表示,但始终包含尾随零
【发布时间】:2013-11-13 01:31:34
【问题描述】:

我正在编写一个函数,该函数需要将浮点值转换为要传递给(封闭)C 代码的字符串。字符串转换是我的代码中最慢的部分,输入数组可能非常大。 sprintf 速度很快,g 转换字符导致紧凑的表示:

x = [-1.75 0 1 pi 2^57];
sprintf('%.17g ',x)

返回

-1.75 0 1 3.1415926535897931 1.4411518807585587e+17 

sprintf 的C 等效项一样,insignificant zeros are not printed 在指定gG 转换字符时。但是,我使用的 C 代码要求数值包括小数点和尾随零。保持相同精度的另一个选项是:

x = [-1.75 0 1 pi 2^57];
sprintf('%.17f ',x)

返回

-1.75000000000000000 0.00000000000000000 1.00000000000000000 3.14159265358979312 144115188075855872.00000000000000000

但这会导致字符串数组膨胀(输入向量可能很大且具有复数值)。


如何高效且紧凑地(速度和内存)将我的数字打印到字符串中,同时在需要时添加尾随零并产生这样的输出?

-1.75 0.0 1.0 3.1415926535897931 1.4411518807585587e+17

理想情况下,这可以直接在格式字符串中完成,以便sprintf 可以完成这项工作。如果这不起作用,还有哪些其他选择,最快的是什么? regexprep 太慢了所以别想了。如果您愿意,您可以使用x = repmat([-1.75 0 1 pi 2^57],1e5,1); 作为您的测试数组来进行计时。

【问题讨论】:

    标签: string matlab string-formatting printf


    【解决方案1】:

    首先我定义了我想要使用的格式规范。
    然后我确定哪个是合适的并创建格式规范字符串。

    x = [-1.75 0 1 pi 2^57];
    
    s = {'%.17g ', '%.1f'};
    idx = (x-floor(x) < 0.1 & x < 10^9) + 1;
    fspec = reshape(char(s(idx))', 1, []);
    

    给我

    >> sprintf(fspec, x)
    
    ans =
    
    -1.75 0.0  1.0  3.1415926535897931 1.4411518807585587e+17 
    

    【讨论】:

    • 我喜欢你使用元胞数组的方式。在我的机器和 R2013a 上,这比使用 x = repmat(x,1e5,1); 测试的 sprintf('%.17g ',x) 慢大约七倍。由于更长、更复杂的格式字符串,几乎所有额外的时间都花在了sprintf。能够使用某种形式的单个格式字符串来做到这一点仍然很好。
    • 我目前正在使用它的紧凑版本。似乎sprintf 的许多减速是在使用ge 转换字符打印许多非常大或非常小的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 2010-09-14
    • 2011-02-23
    • 2015-03-26
    • 2022-12-11
    相关资源
    最近更新 更多