Skip to content

Incorrect value for logarithm of small numbers (denormal floats) #24887

@ScoreUnder

Description

@ScoreUnder

Zig Version

0.14.1

Steps to Reproduce and Observed Behavior

calculate ln(287.26582147382784e-310) via @log or std.math.log:

test {
    // expected value sourced from Wolfram Alpha
    const expected: f64 = -711.8181974647329933991007419903441317012207784976779687026632850985;
    var value: f64 = 7.26582147382784e-310;
    const tolerance: f64 = std.math.sqrt(std.math.floatEps(f64));

    std.mem.doNotOptimizeAway(&value); // ensure the compiler doesn't cleverly replace @log at compile time (it gets it right...?)

    const other_fun_logarithms = struct {
        pub fn ln_by_log2(x: anytype) @TypeOf(x) {
            return @log2(x) * std.math.ln2;
        }
        pub fn ln_by_log10(x: anytype) @TypeOf(x) {
            return @log10(x) * std.math.ln10;
        }
    };

    try std.testing.expectApproxEqRel(expected, other_fun_logarithms.ln_by_log2(value), tolerance);
    try std.testing.expectApproxEqRel(expected, other_fun_logarithms.ln_by_log10(value), tolerance);
    try std.testing.expectApproxEqRel(expected, @log(value), tolerance);
    try std.testing.expectApproxEqRel(expected, std.math.log(f64, std.math.e, value), tolerance);
}

@log and std.math.log give -7.464873809916107e2, which is almost 5% away from the actual answer.
@log2 and @log10 give the correct answer.

Expected Behavior

ln(287.26582147382784e-310) ≈ 711.8

https://www.wolframalpha.com/input?i=ln%287.26582147382784e-310%29

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions