#Confusion about usize and comptime types and how to interact with them.

1 messages · Page 1 of 1 (latest)

novel ferry
#

I'm attempting to solve the sieve of Eratosthenes in exercism, and I'm running into a problem with compile some variables created in a for loop. In my function I try to create all candidate numbers up to some limit using a for loop and put them into an array to be searched.

I tried putting a guard in the for loop that checks if the candidate is at the limit and to stop generating candidates if so.

I'm getting a compile time error saying that it's expecting a u32, but gets a usize. I tried casting the range value to u32 to no avail. I read through the docs but I'm still pretty confused.

Here's my code, forgive the first pass sloppiness:

pub fn primes(buffer: []u32, limit: u32) []u32 {
    var candidates: [998]u32 = undefined;
    var marks: [998]bool = undefined;
    for (&candidates, 2..1000) |*candidate, i| {
        if (@intCast(u32, i) >= limit) break;
        candidate.* = @as(u32, i);
    }

    var start_pos: u32 = 0;
    while (start_pos <= candidates.len) {
        for (candidates[start_pos..], start_pos..) |c, i| {
            if (marks[i]) continue;
            marks[i] = (c % candidates[start_pos]) == 0;
        }
        for (marks[start_pos..], start_pos..) |m, i| {
            if (!m) {
                start_pos = i;
                continue;
            }
        }
        break;
    }
    var buf_pos = 0;
    for (marks, candidates) |m, c| {
        if (m)  {
            buffer[buf_pos] = c;
            buf_pos += 1;
        }
    }
    return buffer[0..];
}

Here's the error:

sieve.zig:5:30: error: expected type 'u32', found 'usize'
        if (@intCast(u32, i) >= limit) break;
            ~~~~~~~~~~~~~~~~~^~~~~~~~
sieve.zig:5:30: note: unsigned 32-bit int cannot represent all possible unsigned 64-bit values
referenced by:
    test.find primes up to 1000: test_sieve.zig:56:25
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

What part of the docs should I be looking in to understand why this isn't working?

topaz hamlet
#

There should not be an error there, even without the @intCast. if(usize >= u32) should just coerce the second parameter to usize and just work.
This looks like zig is getting confused about the error location. I think there were a few bugs like these in the 0.10 compiler. What version of zig are you using?

To fix this you could try to fix all the other errors of this type:
candidate.* = @as(u32, i);candidate.* = @intCast(u32, i); type:
start_pos = i;start_pos = @intCast(u32, i); type:
buffer[buf_pos] = c;buffer[buf_pos] = @intCast(u32, c);

novel ferry
#

This is my zig version 0.11.0-dev.2191+30427ff79 It's pretty recent.

topaz hamlet
#

Replacing the @as(u32, i) with @intCast(u32, i) should fix it.

novel ferry
#

Okay cool that got it compiling. So the way I wrote it the first time should work in theory?

#

I'm still trying to wrap my mind around these lower level data types, still very perplexing when I think something should work or shouldn't need a type specified, but it does.

topaz hamlet
topaz hamlet