std.math Funções em Zig — Referência e Exemplos

std.math Funções — Referência Detalhada

Este documento serve como referência completa para todas as funções matemáticas disponíveis no std.math, organizadas por categoria. Cada função opera em tipos de ponto flutuante (f16, f32, f64, f128) e usa os builtins do Zig quando disponíveis, aproveitando instruções SIMD e de hardware quando possível.

Funções Trigonométricas

const math = std.math;

// Funções básicas (argumento em radianos)
math.sin(x)     // Seno
math.cos(x)     // Cosseno
math.tan(x)     // Tangente

// Funções inversas
math.asin(x)    // Arco seno (retorna radianos)
math.acos(x)    // Arco cosseno
math.atan(x)    // Arco tangente
math.atan2(y, x) // Arco tangente de y/x (quadrante correto)

// Hiperbólicas
math.sinh(x)    // Seno hiperbólico
math.cosh(x)    // Cosseno hiperbólico
math.tanh(x)    // Tangente hiperbólica
math.asinh(x)   // Arco seno hiperbólico
math.acosh(x)   // Arco cosseno hiperbólico
math.atanh(x)   // Arco tangente hiperbólica

Funções Exponenciais e Logarítmicas

math.exp(x)     // e^x
math.exp2(x)    // 2^x
math.log(x)     // ln(x) — logaritmo natural
math.log2(x)    // log₂(x)
math.log10(x)   // log₁₀(x)
math.pow(T, base, exp) // base^exp
math.sqrt(x)    // Raiz quadrada
math.cbrt(x)    // Raiz cúbica
math.hypot(x, y) // sqrt(x² + y²) sem overflow

Funções de Arredondamento

math.floor(x)   // Arredonda para baixo
math.ceil(x)    // Arredonda para cima
math.round(x)   // Arredonda para o mais próximo
math.trunc(x)   // Trunca a parte fracionária

// Para inteiros
math.divCeil(T, a, b)   // Divisão arredondada para cima
math.divFloor(T, a, b)  // Divisão arredondada para baixo
math.divTrunc(T, a, b)  // Divisão truncada
math.divExact(T, a, b)  // Divisão exata (erro se não divide)

Funções de Comparação e Seleção

math.min(a, b)       // Menor valor
math.max(a, b)       // Maior valor
math.clamp(v, lo, hi) // Limita v ao intervalo [lo, hi]
math.order(a, b)     // Retorna .lt, .eq, ou .gt

Exemplo 1: Calculadora Científica

const std = @import("std");
const math = std.math;

fn grausParaRad(graus: f64) f64 {
    return graus * math.pi / 180.0;
}

fn radParaGraus(rad: f64) f64 {
    return rad * 180.0 / math.pi;
}

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.writeAll("=== Calculadora Científica ===\n\n");

    // Tabela trigonométrica
    try stdout.print("{s:>8} {s:>10} {s:>10} {s:>10}\n", .{
        "Graus", "sin", "cos", "tan",
    });
    try stdout.print("{s:->8} {s:->10} {s:->10} {s:->10}\n", .{
        "", "", "", "",
    });

    const angulos = [_]f64{ 0, 30, 45, 60, 90 };
    for (angulos) |graus| {
        const rad = grausParaRad(graus);
        try stdout.print("{d:>8.0} {d:>10.6} {d:>10.6} ", .{
            graus,
            math.sin(rad),
            math.cos(rad),
        });
        if (graus == 90) {
            try stdout.writeAll("       inf\n");
        } else {
            try stdout.print("{d:>10.6}\n", .{math.tan(rad)});
        }
    }

    // Logaritmos
    try stdout.writeAll("\n--- Logaritmos ---\n");
    const bases = [_]f64{ 1, 2, math.e, 10, 100, 1000 };
    for (bases) |x| {
        try stdout.print("  ln({d:>6.2}) = {d:>8.4}  log2 = {d:>8.4}  log10 = {d:>8.4}\n", .{
            x,
            math.log(x),
            math.log2(x),
            math.log10(x),
        });
    }

    // Potências e raízes
    try stdout.writeAll("\n--- Potências e Raízes ---\n");
    try stdout.print("  2^16 = {d:.0}\n", .{math.pow(f64, 2.0, 16.0)});
    try stdout.print("  sqrt(2) = {d:.10}\n", .{math.sqrt(@as(f64, 2.0))});
    try stdout.print("  cbrt(27) = {d:.10}\n", .{math.cbrt(@as(f64, 27.0))});
    try stdout.print("  hypot(3,4) = {d:.10}\n", .{math.hypot(@as(f64, 3.0), @as(f64, 4.0))});
}

Exemplo 2: Arredondamento e Divisão

const std = @import("std");
const math = std.math;

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    // Arredondamento de floats
    try stdout.writeAll("=== Arredondamento ===\n\n");
    const valores = [_]f64{ 2.3, 2.5, 2.7, -2.3, -2.5, -2.7 };

    try stdout.print("{s:>6} {s:>6} {s:>6} {s:>6} {s:>6}\n", .{
        "valor", "floor", "ceil", "round", "trunc",
    });

    for (valores) |v| {
        try stdout.print("{d:>6.1} {d:>6.1} {d:>6.1} {d:>6.1} {d:>6.1}\n", .{
            v,
            @floor(v),
            @ceil(v),
            @round(v),
            @trunc(v),
        });
    }

    // Divisão inteira
    try stdout.writeAll("\n=== Divisão Inteira ===\n\n");
    const pares = [_][2]i32{ .{ 7, 3 }, .{ -7, 3 }, .{ 7, -3 }, .{ 10, 5 } };

    try stdout.print("{s:>4} {s:>4} {s:>8} {s:>8} {s:>8}\n", .{
        "a", "b", "divCeil", "divFloor", "divTrunc",
    });

    for (pares) |par| {
        const a = par[0];
        const b = par[1];
        try stdout.print("{d:>4} {d:>4} {d:>8} {d:>8} {d:>8}\n", .{
            a,
            b,
            math.divCeil(i32, a, b) catch 0,
            math.divFloor(i32, a, b) catch 0,
            math.divTrunc(i32, a, b) catch 0,
        });
    }
}

Exemplo 3: Curva de Bezier e Interpolação

const std = @import("std");
const math = std.math;

fn lerp(a: f64, b: f64, t: f64) f64 {
    return a + (b - a) * math.clamp(t, 0.0, 1.0);
}

fn smoothstep(t: f64) f64 {
    const x = math.clamp(t, 0.0, 1.0);
    return x * x * (3.0 - 2.0 * x);
}

fn easeInOut(t: f64) f64 {
    if (t < 0.5) {
        return 2.0 * t * t;
    } else {
        return 1.0 - math.pow(f64, -2.0 * t + 2.0, 2.0) / 2.0;
    }
}

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.writeAll("=== Funções de Interpolação ===\n\n");
    try stdout.print("{s:>4} {s:>8} {s:>10} {s:>10} {s:>10}\n", .{
        "t", "linear", "smoothstep", "easeInOut", "sin",
    });

    var i: usize = 0;
    while (i <= 10) : (i += 1) {
        const t: f64 = @as(f64, @floatFromInt(i)) / 10.0;
        try stdout.print("{d:>4.1} {d:>8.4} {d:>10.4} {d:>10.4} {d:>10.4}\n", .{
            t,
            lerp(0.0, 1.0, t),
            smoothstep(t),
            easeInOut(t),
            math.sin(t * math.pi / 2.0),
        });
    }

    // Clamping de valores
    try stdout.writeAll("\n=== Clamp ===\n");
    const testes = [_]f64{ -2.0, 0.0, 0.5, 1.0, 1.5, 3.0 };
    for (testes) |v| {
        try stdout.print("  clamp({d:>5.1}, 0, 1) = {d:.1}\n", .{
            v, math.clamp(v, 0.0, 1.0),
        });
    }
}

Módulos Relacionados

Tutoriais e Receitas Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.