Display variable in engineering format with the exponent of 10 being a multiple of 3

Dear Scilab team,

I am trying to find a way to display variable in engineering format with the exponent of 10 being a multiple of 3.
So that I can easily deduce the prefix like: giga, kilo, milli, micro, nano, pico.
Example of my code:
→ format(‘e’,24);
→ a = 10000; // 10k
→ a
a =
1.00000000000000000D+04

I would like to display a = 10.0000D+03.

Do you function for that or some format settings ?

__ Thank you in advance __
Regards
Cedric

Hello,

Scilab uses the Engineering notation - Wikipedia, which has some disadvantages compared to SI notation, and there is no built-in feature to replace the actual display by a SI compliant display, you will have to code it yourself.

S.

Here is a small code adapted from Printing floating-point numbers in C using "engineering notation" and SI prefixes to display scalars with SI exponent or SI prefix:

function out = eng(value, prefix, digits)
    // adapted from https://jkorpela.fi/c/eng.html
    arguments
        value double {mustBeReal,mustBeScalar(value)}
        prefix boolean {mustBeScalar(prefix)} = %f
        digits double {mustBeInteger} = format()(2)-6
    end

    PREFIX_START=-24;
    // Smallest power of then for which there is a prefix defined.
    // If the set of prefixes will be extended, change this constant
    // and update the table "prefix".
    prefixstr=["y", "z", "a", "f", "p", "n", "μ", "m", "",...
    "k", "M", "G", "T", "P", "E", "Z", "Y"];
    PREFIX_END = PREFIX_START+(size(prefixstr,"*")-1)*3;

    if  value==0 || isinf(value) || isnan(value)
        out = "";
        return
    end

    if value < 0.0
        sign_ = "-";
        value = -value;
    else
        sign_ = "";
    end

    // correctly round to desired precision
    expof10 = int16(round(floor(log10(value))));
    value = value* 10^(digits - 1 - double(expof10));

    display = fix(value);
    fract = value-display;

    if fract >= 0.5
        display = display + 1.0;
    end

    value = display * 10^(double(expof10) - digits + 1);

    if expof10 > 0
        expof10 = (expof10/3)*3;
    else
        expof10 = ((-expof10+3)/3)*(-3);
    end

    value = value*10.0^double(-expof10);
    if value >= 1000.0
        value =value / 1000.0;
        expof10 = expof10+3;
    elseif value >= 100.0
        digits = digits - 2;
    elseif value >= 10.0
        digits = digits - 1;
    end

    if ~prefix || (expof10 < PREFIX_START) || (expof10 > PREFIX_END)
        out = sprintf("%s%.*fD%+03d", sign_, digits-1, value, expof10);
    else
        out = sprintf("%s%.*f %s", sign_, digits-1, value, prefixstr(1+(expof10-PREFIX_START)/3));
    end
endfunction

for example, for %pi*1e5 the function eng() above yields

--> eng(%pi*1e5,%f,10)

 ans = 

  "314.1592654D+03"

--> eng(%pi*1e5,%t,10)

 ans = 

  "314.1592654 k"

Hello Mr Mottelet.

Thank you for the source code in C.
The ticket can be closed.

Regards.
Cedric

1 Like

See Add engineering format implementation (!1599) · Merge requests · scilab / scilab · GitLab with a much simpler implementation.