Changed add ans sub to prevent losing info
This commit is contained in:
parent
b3cee0588f
commit
eb02b3eb96
59
src/main.zig
59
src/main.zig
@ -45,16 +45,34 @@ pub fn Quantity(T: type, d: Dimensions, s: Scales) type {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(self: Self, rhs: anytype) Self {
|
pub fn add(self: Self, rhs: anytype) Quantity(
|
||||||
|
T,
|
||||||
|
dims,
|
||||||
|
scales.min(@TypeOf(rhs).scales),
|
||||||
|
) {
|
||||||
if (comptime !dims.eql(@TypeOf(rhs).dims))
|
if (comptime !dims.eql(@TypeOf(rhs).dims))
|
||||||
@compileError("Dimension mismatch in add");
|
@compileError("Dimension mismatch in add");
|
||||||
return .{ .value = self.value + rhs.to(Self).value };
|
|
||||||
|
const TargetType = Quantity(T, dims, scales.min(@TypeOf(rhs).scales));
|
||||||
|
const lhs_converted = self.to(TargetType);
|
||||||
|
const rhs_converted = rhs.to(TargetType);
|
||||||
|
|
||||||
|
return .{ .value = lhs_converted.value + rhs_converted.value };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub(self: Self, rhs: anytype) Self {
|
pub fn sub(self: Self, rhs: anytype) Quantity(
|
||||||
|
T,
|
||||||
|
dims,
|
||||||
|
scales.min(@TypeOf(rhs).scales),
|
||||||
|
) {
|
||||||
if (comptime !dims.eql(@TypeOf(rhs).dims))
|
if (comptime !dims.eql(@TypeOf(rhs).dims))
|
||||||
@compileError("Dimension mismatch in sub");
|
@compileError("Dimension mismatch in sub");
|
||||||
return .{ .value = self.value - rhs.to(Self).value };
|
|
||||||
|
const TargetType = Quantity(T, dims, scales.min(@TypeOf(rhs).scales));
|
||||||
|
const lhs_converted = self.to(TargetType);
|
||||||
|
const rhs_converted = rhs.to(TargetType);
|
||||||
|
|
||||||
|
return .{ .value = lhs_converted.value - rhs_converted.value };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mulBy(self: Self, rhs: anytype) Quantity(
|
pub fn mulBy(self: Self, rhs: anytype) Quantity(
|
||||||
@ -155,21 +173,30 @@ pub fn QuantityVec3(Q: type) type {
|
|||||||
return .{ .x = v, .y = v, .z = v };
|
return .{ .x = v, .y = v, .z = v };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(self: Self, rhs: anytype) Self {
|
pub fn add(self: Self, rhs: anytype) QuantityVec3(Quantity(T, d, s.min(@TypeOf(rhs).scales))) {
|
||||||
const Tr = @TypeOf(rhs);
|
const Tr = @TypeOf(rhs);
|
||||||
|
// We leverage the logic in the scalar Quantity.add
|
||||||
|
const qx = (Q{ .value = self.x }).add(Tr.QuantityType{ .value = rhs.x });
|
||||||
|
const qy = (Q{ .value = self.y }).add(Tr.QuantityType{ .value = rhs.y });
|
||||||
|
const qz = (Q{ .value = self.z }).add(Tr.QuantityType{ .value = rhs.z });
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.x = (Q{ .value = self.x }).add(Tr.QuantityType{ .value = rhs.x }).value,
|
.x = qx.value,
|
||||||
.y = (Q{ .value = self.y }).add(Tr.QuantityType{ .value = rhs.y }).value,
|
.y = qy.value,
|
||||||
.z = (Q{ .value = self.z }).add(Tr.QuantityType{ .value = rhs.z }).value,
|
.z = qz.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub(self: Self, rhs: anytype) Self {
|
pub fn sub(self: Self, rhs: anytype) QuantityVec3(Quantity(T, d, s.min(@TypeOf(rhs).scales))) {
|
||||||
const Tr = @TypeOf(rhs);
|
const Tr = @TypeOf(rhs);
|
||||||
|
const qx = (Q{ .value = self.x }).sub(Tr.QuantityType{ .value = rhs.x });
|
||||||
|
const qy = (Q{ .value = self.y }).sub(Tr.QuantityType{ .value = rhs.y });
|
||||||
|
const qz = (Q{ .value = self.z }).sub(Tr.QuantityType{ .value = rhs.z });
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.x = (Q{ .value = self.x }).sub(Tr.QuantityType{ .value = rhs.x }).value,
|
.x = qx.value,
|
||||||
.y = (Q{ .value = self.y }).sub(Tr.QuantityType{ .value = rhs.y }).value,
|
.y = qy.value,
|
||||||
.z = (Q{ .value = self.z }).sub(Tr.QuantityType{ .value = rhs.z }).value,
|
.z = qz.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,15 +345,15 @@ test "Add" {
|
|||||||
try std.testing.expectEqual(1, @TypeOf(added2).dims.get(.L));
|
try std.testing.expectEqual(1, @TypeOf(added2).dims.get(.L));
|
||||||
std.debug.print("KiloMeter {f} + {f} = {f} OK\n", .{ distance, distance3, added2 });
|
std.debug.print("KiloMeter {f} + {f} = {f} OK\n", .{ distance, distance3, added2 });
|
||||||
|
|
||||||
const added3 = distance3.add(distance);
|
const added3 = distance3.add(distance).to(KiloMeter);
|
||||||
try std.testing.expectEqual(2, added3.value);
|
try std.testing.expectEqual(2, added3.value);
|
||||||
try std.testing.expectEqual(1, @TypeOf(added3).dims.get(.L));
|
try std.testing.expectEqual(1, @TypeOf(added3).dims.get(.L));
|
||||||
std.debug.print("KiloMeter {f} + {f} = {f} OK\n", .{ distance3, distance, added3 });
|
std.debug.print("KiloMeter {f} + {f} = {f} OK\n", .{ distance3, distance, added3 });
|
||||||
|
|
||||||
const KiloMeter_f = Quantity(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
const KiloMeter_f = Quantity(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||||
const distance4 = KiloMeter_f{ .value = 2 };
|
const distance4 = KiloMeter_f{ .value = 2 };
|
||||||
const added4 = distance4.add(distance);
|
const added4 = distance4.add(distance).to(KiloMeter_f);
|
||||||
try std.testing.expectEqual(2.01, added4.value);
|
try std.testing.expectApproxEqAbs(2.01, added4.value, 0.000001);
|
||||||
try std.testing.expectEqual(1, @TypeOf(added4).dims.get(.L));
|
try std.testing.expectEqual(1, @TypeOf(added4).dims.get(.L));
|
||||||
std.debug.print("KiloMeter_f {f} + {f} = {f} OK\n", .{ distance4, distance, added4 });
|
std.debug.print("KiloMeter_f {f} + {f} = {f} OK\n", .{ distance4, distance, added4 });
|
||||||
}
|
}
|
||||||
@ -349,7 +376,7 @@ test "Sub" {
|
|||||||
const km_f = KiloMeter_f{ .value = 2.5 };
|
const km_f = KiloMeter_f{ .value = 2.5 };
|
||||||
const m_f = Meter{ .value = 500 };
|
const m_f = Meter{ .value = 500 };
|
||||||
const diff3 = km_f.sub(m_f);
|
const diff3 = km_f.sub(m_f);
|
||||||
try std.testing.expectApproxEqAbs(@as(f32, 2.0), diff3.value, 1e-4);
|
try std.testing.expectApproxEqAbs(2000, diff3.value, 1e-4);
|
||||||
std.debug.print("Sub float cross-scale: {f} - {f} = {f} OK\n", .{ km_f, m_f, diff3 });
|
std.debug.print("Sub float cross-scale: {f} - {f} = {f} OK\n", .{ km_f, m_f, diff3 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user