Function setFloatString [src]
Set a Rational from a string of the form A/B where A and B are base-10 integers.
Prototype
pub fn setFloatString(self: *Rational, str: []const u8) !void
Parameters
self: *Rational
str: []const u8
Source
pub fn setFloatString(self: *Rational, str: []const u8) !void {
// TODO: Accept a/b fractions and exponent form
if (str.len == 0) {
return error.InvalidFloatString;
}
const State = enum {
Integer,
Fractional,
};
var state = State.Integer;
var point: ?usize = null;
var start: usize = 0;
if (str[0] == '-') {
start += 1;
}
for (str, 0..) |c, i| {
switch (state) {
State.Integer => {
switch (c) {
'.' => {
state = State.Fractional;
point = i;
},
'0'...'9' => {
// okay
},
else => {
return error.InvalidFloatString;
},
}
},
State.Fractional => {
switch (c) {
'0'...'9' => {
// okay
},
else => {
return error.InvalidFloatString;
},
}
},
}
}
// TODO: batch the multiplies by 10
if (point) |i| {
try self.p.setString(10, str[0..i]);
const base = IntConst{ .limbs = &[_]Limb{10}, .positive = true };
var local_buf: [@sizeOf(Limb) * Int.default_capacity]u8 align(@alignOf(Limb)) = undefined;
var fba = std.heap.FixedBufferAllocator.init(&local_buf);
const base_managed = try base.toManaged(fba.allocator());
var j: usize = start;
while (j < str.len - i - 1) : (j += 1) {
try self.p.ensureMulCapacity(self.p.toConst(), base);
try self.p.mul(&self.p, &base_managed);
}
try self.q.setString(10, str[i + 1 ..]);
try self.p.add(&self.p, &self.q);
try self.q.set(1);
var k: usize = i + 1;
while (k < str.len) : (k += 1) {
try self.q.mul(&self.q, &base_managed);
}
try self.reduce();
} else {
try self.p.setString(10, str[0..]);
try self.q.set(1);
}
}