Seg fault in std.math.big.Ratio

I am using 0.14.0-dev.2802+257054a14 and wrote a snippet to understand the use of std.math.Ratio:

pub fn main() !void {
    const iters = 98;
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    var x = try math.big.Rational.init(allocator);
    var gamma = try math.big.Rational.init(allocator);
    try gamma.setRatio(40 - 1, 40);
    try x.setRatio(1, 1);
    for (0..iters) |i| {
        x.mul(x, gamma) catch |err| {
            std.debug.print("got err {} at {}\n", .{ err, i });
            break;
        };
    }
    const res = try x.toFloat(f128);
    std.debug.print("{}\n", .{res});
}

it seg faults in the last iteration (98) and I don’t understand why. I lookup the doc of mul and setRatio and it should work fine if the modified ratio is also an input.
It also takes an extra iteration or two to seg fault in zig version 0.13 or 0.12 .
Is there a more natural way to use the library that I am not aware of or even a correct way?

It seems to not handle the aliasing correctly, looks like an implementation bug to me.
You could try using a temporary copy:

        temp.mul(x, gamma) catch |err| {...};
        std.mem.swap(std.math.big.Rational, &temp, &x);

The documentation states that it’s faster to avoid aliasing of the parameters anyways, so that’s what you should probably do anyways.

1 Like

not the first implementation bug in big int related to aliasing. Strange how they only appear in big ints.