Added Imperial unit scales
This commit is contained in:
parent
a91a509368
commit
f26f6086ca
@ -749,6 +749,61 @@ test "add/sub bare number on dimensionless scalar" {
|
|||||||
try std.testing.expectEqual(7, c.value);
|
try std.testing.expectEqual(7, c.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Imperial length scales" {
|
||||||
|
const Foot = Scalar(f64, .{ .L = 1 }, .{ .L = .ft });
|
||||||
|
const Meter = Scalar(f64, .{ .L = 1 }, .{});
|
||||||
|
const Inch = Scalar(f64, .{ .L = 1 }, .{ .L = .inch });
|
||||||
|
const CentiMeter = Scalar(f64, .{ .L = 1 }, .{ .L = .c });
|
||||||
|
const Mile = Scalar(f64, .{ .L = 1 }, .{ .L = .mi });
|
||||||
|
const KiloMeter = Scalar(f64, .{ .L = 1 }, .{ .L = .k });
|
||||||
|
const Yard = Scalar(f64, .{ .L = 1 }, .{ .L = .yd });
|
||||||
|
|
||||||
|
// 1 ft → 0.3048 m
|
||||||
|
const one_ft = Foot{ .value = 1.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(0.3048, one_ft.to(Meter).value, 1e-9);
|
||||||
|
|
||||||
|
// 12 in → 1 ft
|
||||||
|
const twelve_in = Inch{ .value = 12.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(1.0, twelve_in.to(Foot).value, 1e-9);
|
||||||
|
|
||||||
|
// 1 in → 2.54 cm
|
||||||
|
const one_in = Inch{ .value = 1.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(2.54, one_in.to(CentiMeter).value, 1e-9);
|
||||||
|
|
||||||
|
// 1 mi → 1.609344 km
|
||||||
|
const one_mi = Mile{ .value = 1.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(1.609344, one_mi.to(KiloMeter).value, 1e-9);
|
||||||
|
|
||||||
|
// 3 ft → 1 yd
|
||||||
|
const three_ft = Foot{ .value = 3.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(1.0, three_ft.to(Yard).value, 1e-9);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Imperial mass scales" {
|
||||||
|
const Pound = Scalar(f64, .{ .M = 1 }, .{ .M = .lb });
|
||||||
|
const KiloGram = Scalar(f64, .{ .M = 1 }, .{ .M = .k });
|
||||||
|
const Ounce = Scalar(f64, .{ .M = 1 }, .{ .M = .oz });
|
||||||
|
const Stone = Scalar(f64, .{ .M = 1 }, .{ .M = .st });
|
||||||
|
|
||||||
|
// 1 lb → ~0.453592 kg
|
||||||
|
const one_lb = Pound{ .value = 1.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(0.45359237, one_lb.to(KiloGram).value, 1e-6);
|
||||||
|
|
||||||
|
// 16 oz → 1 lb
|
||||||
|
const sixteen_oz = Ounce{ .value = 16.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(1.0, sixteen_oz.to(Pound).value, 1e-6);
|
||||||
|
|
||||||
|
// 1 stone → 14 lb
|
||||||
|
const one_st = Stone{ .value = 1.0 };
|
||||||
|
try std.testing.expectApproxEqAbs(14.0, one_st.to(Pound).value, 1e-4);
|
||||||
|
|
||||||
|
// 2 lb + 8 oz → 2.5 lb
|
||||||
|
const two_lb = Pound{ .value = 2.0 };
|
||||||
|
const eight_oz = Ounce{ .value = 8.0 };
|
||||||
|
const total = two_lb.add(eight_oz).to(Pound);
|
||||||
|
try std.testing.expectApproxEqAbs(2.5, total.value, 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
test "comparisons with comptime_int on dimensionless scalar" {
|
test "comparisons with comptime_int on dimensionless scalar" {
|
||||||
const DimLess = Scalar(i128, .{}, .{});
|
const DimLess = Scalar(i128, .{}, .{});
|
||||||
const x = DimLess{ .value = 42 };
|
const x = DimLess{ .value = 42 };
|
||||||
|
|||||||
@ -41,6 +41,18 @@ pub const UnitScale = enum(isize) {
|
|||||||
hour = 3_600,
|
hour = 3_600,
|
||||||
year = 31_536_000,
|
year = 31_536_000,
|
||||||
|
|
||||||
|
// Imperial Length (Literal factors in meters)
|
||||||
|
// 1 inch = 0.0254 meters. Since enum backing is isize,
|
||||||
|
// we use a unique tag and handle the float in getFactor.
|
||||||
|
inch = -1001,
|
||||||
|
ft = -1002,
|
||||||
|
yd = -1003,
|
||||||
|
mi = -1004,
|
||||||
|
|
||||||
|
oz = -1005, // 1 oz = 28.3495231 g
|
||||||
|
lb = -1006, // 1 lb = 453.59237 g (= 16 oz)
|
||||||
|
st = -1007, // 1 stone = 6350.29318 g (= 14 lb)
|
||||||
|
|
||||||
// Undefined
|
// Undefined
|
||||||
_,
|
_,
|
||||||
|
|
||||||
@ -48,24 +60,31 @@ pub const UnitScale = enum(isize) {
|
|||||||
var buf: [16]u8 = undefined;
|
var buf: [16]u8 = undefined;
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
inline .none => "",
|
inline .none => "",
|
||||||
inline .P, .T, .G, .M, .k, .h, .da, .d, .c, .m, .u, .n, .p, .f, .min, .hour, .year => @tagName(self),
|
inline .P, .T, .G, .M, .k, .h, .da, .d, .c, .m, .u, .n, .p, .f, .min, .hour, .year, .inch, .ft, .yd, .mi, .oz, .lb, .st => @tagName(self),
|
||||||
else => std.fmt.bufPrint(&buf, "[{d}]", .{@intFromEnum(self)}) catch "[]", // This cannot be inline because of non exhaustive enum, but that's ok, it is just str, not calculation
|
else => std.fmt.bufPrint(&buf, "[{d}]", .{@intFromEnum(self)}) catch "[]", // This cannot be inline because of non exhaustive enum, but that's ok, it is just str, not calculation
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to get the actual scaling factor
|
|
||||||
pub inline fn getFactor(self: @This()) comptime_float {
|
pub inline fn getFactor(self: @This()) comptime_float {
|
||||||
return comptime switch (self) {
|
return comptime switch (self) {
|
||||||
|
// Standard SI Exponents
|
||||||
inline .P, .T, .G, .M, .k, .h, .da, .none, .d, .c, .m, .u, .n, .p, .f => std.math.pow(f64, 10.0, @floatFromInt(@intFromEnum(self))),
|
inline .P, .T, .G, .M, .k, .h, .da, .none, .d, .c, .m, .u, .n, .p, .f => std.math.pow(f64, 10.0, @floatFromInt(@intFromEnum(self))),
|
||||||
inline else => @floatFromInt(@intFromEnum(self)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper to get the actual scaling factor in i32
|
// Time Factors
|
||||||
pub fn getFactorInt(self: @This()) comptime_int {
|
inline .min, .hour, .year => @floatFromInt(@intFromEnum(self)),
|
||||||
return comptime switch (self) {
|
|
||||||
inline .P, .T, .G, .M, .k, .h, .da, .none, .d, .c, .m, .u, .n, .p, .f => std.math.powi(i32, 10.0, @intFromEnum(self)) catch 0,
|
// Imperial Length (metres)
|
||||||
inline else => @intFromEnum(self),
|
inline .inch => 0.0254,
|
||||||
|
inline .ft => 0.3048,
|
||||||
|
inline .yd => 0.9144,
|
||||||
|
inline .mi => 1609.344,
|
||||||
|
|
||||||
|
// Imperial Mass (grams — base unit for M is gram, i.e. .none = 1 g)
|
||||||
|
inline .oz => 28.3495231,
|
||||||
|
inline .lb => 453.59237,
|
||||||
|
inline .st => 6350.29318,
|
||||||
|
|
||||||
|
inline else => @floatFromInt(@intFromEnum(self)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user