mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Add RocDec.toString
This commit is contained in:
parent
66a6080f25
commit
c7272766fc
1 changed files with 126 additions and 0 deletions
|
@ -8,6 +8,7 @@ pub const RocDec = struct {
|
|||
num: i128,
|
||||
|
||||
pub const decimal_places: comptime u32 = 18;
|
||||
const max_digits: comptime u32 = 39;
|
||||
|
||||
pub const min: comptime RocDec = .{ .num = math.minInt(i128) };
|
||||
pub const max: comptime RocDec = .{ .num = math.maxInt(i128) };
|
||||
|
@ -108,6 +109,60 @@ pub const RocDec = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn toString(self: RocDec) ?RocStr {
|
||||
var num_bytes: [max_digits]u8 = undefined;
|
||||
var num_digits = std.fmt.formatIntBuf(num_bytes[0..], self.num, 10, false, .{});
|
||||
|
||||
var before_num_digits = num_digits - decimal_places;
|
||||
|
||||
var index = decimal_places - 1;
|
||||
var trim_index: ?usize = null;
|
||||
var is_consecutive_zero = true;
|
||||
while (index != 0) {
|
||||
var digit = num_bytes[before_num_digits + index];
|
||||
if (digit == '0' and is_consecutive_zero) {
|
||||
trim_index = index;
|
||||
} else {
|
||||
is_consecutive_zero = false;
|
||||
}
|
||||
index -= 1;
|
||||
}
|
||||
var after_num_digits = if (trim_index) |i| i else decimal_places;
|
||||
|
||||
const should_add_prefix_zero = before_num_digits == 0 or (before_num_digits == 1 and num_bytes[0] == '-');
|
||||
const prefix_zero_len: usize = if (should_add_prefix_zero) 1 else 0;
|
||||
const dot_len: usize = 1;
|
||||
var str_len = prefix_zero_len + before_num_digits + dot_len + after_num_digits;
|
||||
|
||||
// [max_digits + 2] here to account for '.' and '-'
|
||||
var str_bytes: [max_digits + 2]u8 = undefined;
|
||||
|
||||
var str_bytes_index: usize = 0;
|
||||
var bytes_index: usize = 0;
|
||||
if (should_add_prefix_zero) {
|
||||
if (num_bytes[bytes_index] == '-') {
|
||||
str_bytes[str_bytes_index] = '-';
|
||||
str_bytes_index += 1;
|
||||
bytes_index += 1;
|
||||
}
|
||||
str_bytes[str_bytes_index] = '0';
|
||||
str_bytes_index += 1;
|
||||
}
|
||||
|
||||
while (bytes_index < str_len) {
|
||||
if (bytes_index == before_num_digits) {
|
||||
str_bytes[str_bytes_index] = '.';
|
||||
str_bytes_index += 1;
|
||||
}
|
||||
|
||||
str_bytes[str_bytes_index] = num_bytes[bytes_index];
|
||||
str_bytes_index += 1;
|
||||
bytes_index += 1;
|
||||
}
|
||||
|
||||
return RocStr.init(&str_bytes, str_len);
|
||||
}
|
||||
|
||||
pub fn negate(self: RocDec) ?RocDec {
|
||||
var negated = math.negate(self.num) catch null;
|
||||
return if (negated) |n| .{ .num = n } else null;
|
||||
|
@ -319,6 +374,7 @@ fn mul_u128(a: u128, b: u128) U256 {
|
|||
|
||||
const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const expect = testing.expect;
|
||||
|
||||
test "fromU64" {
|
||||
var dec = RocDec.fromU64(25);
|
||||
|
@ -431,6 +487,76 @@ test "fromString: .123.1" {
|
|||
expectEqual(dec, null);
|
||||
}
|
||||
|
||||
test "toString: 123.45" {
|
||||
var roc_str = RocStr.init("123.45", 6);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: -123.45" {
|
||||
var roc_str = RocStr.init("-123.45", 7);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: 123.0" {
|
||||
var roc_str = RocStr.init("123.0", 5);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: -123.0" {
|
||||
var roc_str = RocStr.init("-123.0", 6);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: 0.45" {
|
||||
var roc_str = RocStr.init("0.45", 4);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: -0.45" {
|
||||
var roc_str = RocStr.init("-0.45", 5);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: -111.123456789" {
|
||||
var roc_str = RocStr.init("-111.123456789", 14);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: 111.1234567891" {
|
||||
var roc_str = RocStr.init("111.1234567891", 14);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "toString: 123.111111111111 (big str)" {
|
||||
var roc_str = RocStr.init("123.111111111111", 16);
|
||||
var dec = RocDec.fromString(roc_str);
|
||||
var res_roc_str = dec.?.toString();
|
||||
expect(RocStr.eq(roc_str, res_roc_str.?));
|
||||
}
|
||||
|
||||
test "add: 0" {
|
||||
var dec: RocDec = .{ .num = 0 };
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue