通过 sprintf() 和 fprintf() 的 Matlab ShortEng 数字格式?

Matlab ShortEng number format via sprintf() and fprintf()?

我喜欢在交互式命令中使用 MATLAB 的 shortEng 符号 Window:

>> a = 123e-12;
>> disp(a);

   1.2300e-10       % Scientific notation. Urgh!

>> format shortEng;
>> disp(a);

   123.0000e-012    % Engineering notation! :-D

但是我想用fprintf:

>> format shortEng;
>> fprintf('%0.3e', a); 
1.2300e-10          % Scientific. Urgh!

如何使用 MATLAB Format Operators 以工程格式使用 fprintf 或 sprintf 打印值?

我知道我可以编写自己的函数来将值格式化为字符串,但我正在寻找已经内置到 MATLAB 中的东西。

注意:"Engineering" 表示法与 "Scientific" 的不同之处在于指数始终是 3 的倍数。

>> fprintf('%0.3e', a);    % This is Scientific notation.
1.230000e-10

您可以使用以下实用程序:

http://www.people.fas.harvard.edu/~arcrock/lib118/numutil/unpacknum.m

这也会根据给定的数字 N 解压缩数字,并确保指数是 N 的倍数。通过输入 N=3 你就有了工程符号。

更详细地说,unpacknum 有 3 个参数:数字 x、基数(10,如果你想要工程符号)和值 N3 如果你想要工程符号)和它 returns 你可以在 fprintf() 中使用的一对 (f,e).

查看 unpacknum 帮助以获取快速示例。

无法直接使用 fprintf 格式说明符来表示您需要的格式。一种解决方法是使用 disp 的输出作为要打印的字符串。但是 disp 不是 return 字符串,它直接写入标准输出。那么,如何做到这一点?

这里是 evalc(带输出捕获的评估)的救星:

%// Create helper function
sdisp = @(x) strtrim(evalc(sprintf('disp(%g)', x)));

%// Test helper function
format ShortEng;
a = 123e-12;
fprintf(1, 'Test: %s', sdisp(a));

当然,这是一种解决方法,并且由于辅助函数的输入未经测试,可能会以多种方式适得其反。但它说明了一点,并且是极少数情况下被辱骂的 eval 函数族实际上是不可替代的。

此函数将一个值转换为工程符号中的字符串:

function sNum = engn(value)
exp= floor(log10(abs(value)));
if ( (exp < 3) && (exp >=0) ) 
    exp = 0; % Display without exponent
else
    while (mod(exp, 3))
        exp= exp - 1;
    end
end
frac=value/(10^exp); % Adjust fraction to exponent
if (exp == 0)
    sNum = sprintf('%+8.5G', frac);
else
    sNum = sprintf('%+8.5GE%+.2d', frac, exp);
end
end

您可以根据自己的喜好微调格式。与 fprintf 结合使用非常简单:

fprintf('%s\t%s\n', engn(543210.123), engn(-0.0000567)) % +543.21E+03  -56.7E-06
fprintf('%s\t%s\n', engn(-321.123), engn(876543210)) % -321.12   +876.54E+06

您可以使用以下发布到 MATLAB 文件交换的实用程序: num2eng

它提供了对输出字符串格式和完整输入检查的广泛控制,因此比 user2271770 建议的更简单的 evalc 方法更灵活,更不容易出错。

如果您愿意,它还可以使用 SI 前缀而不是工程符号来输出字符串。