Remove using a string as an intermediate form in Dec.fromF64.

This commit is contained in:
Derek Gustafson 2022-03-03 10:24:05 -05:00
parent d91df42147
commit 6feac21b9b
No known key found for this signature in database
GPG key ID: 27AEEAB1887B89BE

View file

@ -26,21 +26,20 @@ pub const RocDec = extern struct {
return .{ .num = num * one_point_zero_i128 };
}
// TODO: There's got to be a better way to do this other than converting to Str
pub fn fromF64(num: f64) ?RocDec {
var digit_bytes: [19]u8 = undefined; // 19 = max f64 digits + '.' + '-'
var fbs = std.io.fixedBufferStream(digit_bytes[0..]);
std.fmt.formatFloatDecimal(num, .{}, fbs.writer()) catch
return null;
var result: f64 = num * comptime @intToFloat(f64, one_point_zero_i128);
var dec = RocDec.fromStr(RocStr.init(&digit_bytes, fbs.pos));
if (dec) |d| {
return d;
} else {
if (result > comptime @intToFloat(f64, math.maxInt(i128))) {
return null;
}
if (result < comptime @intToFloat(f64, math.minInt(i128))) {
return null;
}
var ret: RocDec = .{ .num = @floatToInt(i128, result) };
return ret;
}
pub fn fromStr(roc_str: RocStr) ?RocDec {
@ -729,6 +728,11 @@ test "fromF64" {
try expectEqual(RocDec{ .num = 25500000000000000000 }, dec.?);
}
test "fromF64 overflow" {
var dec = RocDec.fromF64(1e308);
try expectEqual(dec, null);
}
test "fromStr: empty" {
var roc_str = RocStr.init("", 0);
var dec = RocDec.fromStr(roc_str);