DoxigAlpha

formatScientific

Write a FloatDecimal to a buffer in scientific form.

The buffer provided must be greater than min_buffer_size in length. If no precision is specified, this function will never return an error. If a precision is specified, up to 8 + precision bytes will be written to the buffer. An error will be returned if the content will not fit.

It is recommended to bound decimal formatting with an exact precision.

Function parameters

Parameters

#
T:type
buf:[]u8
f_:FloatDecimal(T)
precision:?usize

Type definitions in this namespace

Types

#

Returns the minimum buffer size needed to print every float of a specific type and format.

Functions

#
bufferSize
Returns the minimum buffer size needed to print every float of a specific type and format.
render
Format a floating-point value and write it to buffer.
formatScientific
Write a FloatDecimal to a buffer in scientific form.
formatDecimal
Write a FloatDecimal to a buffer in decimal form.
binaryToDecimal
Convert a binary float representation to decimal.

Error sets in this namespace

Error Sets

#

Any buffer used for `format` must be at least this large.

Values

#
min_buffer_size
Any buffer used for `format` must be at least this large.

Source

Implementation

#
pub fn formatScientific(comptime T: type, buf: []u8, f_: FloatDecimal(T), precision: ?usize) Error![]const u8 {
    std.debug.assert(buf.len >= min_buffer_size);
    var f = f_;

    if (f.exponent == special_exponent) {
        return copySpecialStr(buf, f);
    }

    if (precision) |prec| {
        f = round(T, f, .scientific, prec);
    }

    var output = f.mantissa;
    const olength = decimalLength(output);

    if (precision) |prec| {
        // fixed bound: sign(1) + leading_digit(1) + point(1) + exp_sign(1) + exp_max(4)
        const req_bytes = 8 + prec;
        if (buf.len < req_bytes) {
            return error.BufferTooSmall;
        }
    }

    // Step 5: Print the scientific representation
    var index: usize = 0;
    if (f.sign) {
        buf[index] = '-';
        index += 1;
    }

    // 1.12345
    writeDecimal(buf[index + 2 ..], &output, olength - 1);
    buf[index] = '0' + @as(u8, @intCast(output % 10));
    buf[index + 1] = '.';
    index += 2;
    const dp_index = index;
    if (olength > 1) index += olength - 1 else index -= 1;

    if (precision) |prec| {
        index += @intFromBool(olength == 1);
        if (prec > olength - 1) {
            const len = prec - (olength - 1);
            @memset(buf[index..][0..len], '0');
            index += len;
        } else {
            index = dp_index + prec - @intFromBool(prec == 0);
        }
    }

    // e100
    buf[index] = 'e';
    index += 1;
    var exp = f.exponent + @as(i32, @intCast(olength)) - 1;
    if (exp < 0) {
        buf[index] = '-';
        index += 1;
        exp = -exp;
    }
    var uexp: u32 = @intCast(exp);
    const elength = decimalLength(uexp);
    writeDecimal(buf[index..], &uexp, elength);
    index += elength;

    return buf[0..index];
}