diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-20 16:41:08 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-20 16:41:08 -0700 |
| commit | c8ded2f9c940be2d59f5e9dc7d66374b67afba63 (patch) | |
| tree | 2a9608fdf705567e3992020e8953b5e391e70b28 /src | |
| parent | 4cb5fed10ba2233a3b19c33b56585eb73da8b001 (diff) | |
| download | zig-c8ded2f9c940be2d59f5e9dc7d66374b67afba63.tar.gz zig-c8ded2f9c940be2d59f5e9dc7d66374b67afba63.zip | |
stage2: implement big int to float conversion
Diffstat (limited to 'src')
| -rw-r--r-- | src/value.zig | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/value.zig b/src/value.zig index fce5e8afb1..7c24cdab81 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1853,17 +1853,26 @@ pub const Value = extern union { }; } - pub fn intToFloat(val: Value, allocator: *Allocator, dest_ty: Type, target: Target) !Value { + pub fn intToFloat(val: Value, arena: *Allocator, dest_ty: Type, target: Target) !Value { switch (val.tag()) { .undef, .zero, .one => return val, .the_only_possible_value => return Value.initTag(.zero), // for i0, u0 .int_u64 => { - return intToFloatInner(val.castTag(.int_u64).?.data, allocator, dest_ty, target); + return intToFloatInner(val.castTag(.int_u64).?.data, arena, dest_ty, target); }, .int_i64 => { - return intToFloatInner(val.castTag(.int_i64).?.data, allocator, dest_ty, target); + return intToFloatInner(val.castTag(.int_i64).?.data, arena, dest_ty, target); + }, + .int_big_positive => { + const limbs = val.castTag(.int_big_positive).?.data; + const float = bigIntToFloat(limbs, true); + return floatToValue(float, arena, dest_ty, target); + }, + .int_big_negative => { + const limbs = val.castTag(.int_big_negative).?.data; + const float = bigIntToFloat(limbs, false); + return floatToValue(float, arena, dest_ty, target); }, - .int_big_positive, .int_big_negative => @panic("big int to float"), else => unreachable, } } @@ -1878,6 +1887,16 @@ pub const Value = extern union { } } + fn floatToValue(float: f128, arena: *Allocator, dest_ty: Type, target: Target) !Value { + switch (dest_ty.floatBits(target)) { + 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)), + 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)), + 64 => return Value.Tag.float_64.create(arena, @floatCast(f64, float)), + 128 => return Value.Tag.float_128.create(arena, float), + else => unreachable, + } + } + /// Supports both floats and ints; handles undefined. pub fn numberAddWrap( lhs: Value, |
