# "Undefined value" error in comptime mathematics

**URL:** <https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436>\
**Category:** Help\
**Tags:** comptime\
**Created:** [October 19, 2024, 11:10am UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436 "2024-10-19T11:10:08Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![MatthewJohnHeath](https://ziggit.dev/user_avatar/ziggit.dev/matthewjohnheath/32/3523_2.png) [@MatthewJohnHeath](https://ziggit.dev/u/MatthewJohnHeath)\
**Post date:** [October 19, 2024, 11:10am UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/1 "2024-10-19T11:10:08Z")

</div>

I am trying to do some mathematics at compile time (towards a library for units of measure) and got an error I don’t understand. I am afraid my attempt to shorten the code to post here is still a little long:

```zig
const std = @import("std");
const testing = std.testing;

pub const ComptimeFraction = struct {
    numerator: comptime_int,
    denominator: comptime_int,
    const Self = @This();

    pub fn init(top: comptime_int, bottom: comptime_int) Self {
        return Self{
            .numerator = top,
            .denominator = bottom,
        };
    }

    pub fn eq(self: Self, other: Self) bool {
        return (self.numerator == other.numerator) and (self.denominator == other.denominator);
    }
};

fn distinctPrimeFactorCount(number: comptime_int) comptime_int {
    comptime var remaining = number;
    comptime var count = 0;
    comptime var p = 2;
    while (remaining > 1) {
        if (remaining % p == 0) {
            count += 1;
            while (remaining % p == 0) {
                remaining /= p;
            }
        }
        p += 1;
    }
    return count;
}

const Factor = struct { prime: comptime_int, power: ComptimeFraction };

fn primeFactorization(number: comptime_int) [distinctPrimeFactorCount(number)]Factor {
    comptime var factorization: [distinctPrimeFactorCount(number)]Factor = undefined;
    comptime var remaining = number;
    comptime var p = 2;
    comptime var i = 0;
    while (i < 0) {
        if (remaining % p == 0) {
            comptime var count = 0;
            while (remaining % p == 0) {
                remaining /= p;
                count += 1;
            }
            factorization[i] = .{ .prime = p, .power = ComptimeFraction.init(count, 1) };
            i += 1;
        }
        p += 1;
    }
    return factorization;
}

test "primeFactorization" {
    try testing.expect(primeFactorization(2)[0].power.eq(ComptimeFraction.init(1, 1)));
}

```

`zig test` on this file failed with

```zig
src/comptime_fraction.zig:17:16: error: use of undefined value here causes undefined behavior
        return (self.numerator == other.numerator) and (self.denominator == other.denominator);
               ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    test.primeFactorization: src/comptime_fraction.zig:60:57

```

I would appreciate any advice.

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [October 19, 2024, 11:33am UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/2 "2024-10-19T11:33:01Z")

</div>

In the body of `primeFactorization` function you never change the `undefined` values of the `factorization` array because you never enter the `while` loop.

---

<div class="post-metadata">

**Author:** ![MatthewJohnHeath](https://ziggit.dev/user_avatar/ziggit.dev/matthewjohnheath/32/3523_2.png) [@MatthewJohnHeath](https://ziggit.dev/u/MatthewJohnHeath)\
**Post date:** [October 19, 2024, 1:21pm UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/3 "2024-10-19T13:21:37Z")

</div>

ugh, thanks! I think I changed that to say 0 temporarily while trying to identify some other bug.

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [October 19, 2024, 6:36pm UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/4 "2024-10-19T18:36:30Z")

</div>

Not answering your question but … why are you defining all this as comptime ?

I think you could write all this as not comptime and if it is called from a comptime part of your code, it will be evaluated at comptime …

---

<div class="post-metadata">

**Author:** ![MatthewJohnHeath](https://ziggit.dev/user_avatar/ziggit.dev/matthewjohnheath/32/3523_2.png) [@MatthewJohnHeath](https://ziggit.dev/u/MatthewJohnHeath)\
**Post date:** [October 19, 2024, 6:55pm UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/5 "2024-10-19T18:55:50Z")

</div>

Probably. I hit some build errors at the very start that seemed to go away when I made comptime more explicit, and decided to do it that way until it builds and does what I intended. Refactoring away unnecessary "comptime"s is in my todos, though.

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [October 21, 2024, 5:19pm UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/6 "2024-10-21T17:19:03Z")

</div>

I was curious so I removed all the comptime definitions and ended up with this error:

```zig
frac.zig:42:62: error: unable to resolve comptime value
fn primeFactorization(number: i64) [distinctPrimeFactorCount(number)]Factor {
                                                             ^ ~~~~~
frac.zig:42:62: note: argument to function being called at comptime must be comptime-known

```

If this error prompted you to comptime everything, I think your problem here is your `primeFactorization` function needs to know the number to factorize at comptime in order to deduce the size of the output array.

In this form this function can only work at comptime. But I think if you change it so it returns a slice instead of an array, the function becomes comptime agnostic, thus simplifying your code.

---

<div class="post-metadata">

**Author:** ![MatthewJohnHeath](https://ziggit.dev/user_avatar/ziggit.dev/matthewjohnheath/32/3523_2.png) [@MatthewJohnHeath](https://ziggit.dev/u/MatthewJohnHeath)\
**Post date:** [October 21, 2024, 6:55pm UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/7 "2024-10-21T18:55:40Z")

</div>

I had assumed I couldn’t allocate and return a slice a slice at comptime, but am I right in thinking that FixedBufferAllocator will work?

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [October 21, 2024, 8:51pm UTC](https://ziggit.dev/t/undefined-value-error-in-comptime-mathematics/6436/8 "2024-10-21T20:51:32Z")

</div>

the following seems to compile.

```zig
const std = @import("std");
const testing = std.testing;

pub const Fraction = struct {
    numerator: i64,
    denominator: i64,
    const Self = @This();

    pub fn init(top: i64, bottom: i64) Self {
        return Self{
            .numerator = top,
            .denominator = bottom,
        };
    }

    pub fn eq(self: Self, other: Self) bool {
        return (self.numerator == other.numerator) and (self.denominator == other.denominator);
    }
};

fn distinctPrimeFactorCount(number: i64) i64 {
    var remaining = number;
    var count = 0;
    var p = 2;
    while (remaining > 1) {
        if (remaining % p == 0) {
            count += 1;
            while (remaining % p == 0) {
                remaining /= p;
            }
        }
        p += 1;
    }
    return count;
}

const Factor = struct {
    prime: i64,
    power: Fraction,
};

fn primeFactorization(comptime number: i64) [distinctPrimeFactorCount(number)]Factor {
    var factorization: [distinctPrimeFactorCount(number)]Factor = undefined;
    var remaining = number;
    comptime var p = 2;
    comptime var i = 0;
    while (i < 0) {
        if (remaining % p == 0) {
            var count = 0;
            while (remaining % p == 0) {
                remaining /= p;
                count += 1;
            }
            factorization[i] = .{
                .prime = p,
                .power = Fraction.init(count, 1),
            };
            i += 1;
        }
        p += 1;
    }
    return factorization;
}

// test "primeFactorization" {
// try testing.expect(primeFactorization(2)[0].power.eq(Fraction.init(1, 1)));
// }

// this is comptime defined
const a = primeFactorization(2);

pub fn main() void {
    std.debug.print("{any}", .{a});
}

```
