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 | |
| parent | 4cb5fed10ba2233a3b19c33b56585eb73da8b001 (diff) | |
| download | zig-c8ded2f9c940be2d59f5e9dc7d66374b67afba63.tar.gz zig-c8ded2f9c940be2d59f5e9dc7d66374b67afba63.zip | |
stage2: implement big int to float conversion
| -rw-r--r-- | src/value.zig | 27 | ||||
| -rw-r--r-- | test/behavior/eval.zig | 16 | ||||
| -rw-r--r-- | test/behavior/eval_stage1.zig | 12 |
3 files changed, 39 insertions, 16 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, diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 950a2b6c10..3d603ff732 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -390,3 +390,19 @@ test "inline for with same type but different values" { } try expect(res == 5); } + +test "f32 at compile time is lossy" { + try expect(@as(f32, 1 << 24) + 1 == 1 << 24); +} + +test "f32 at compile time is lossy" { + try expect(@as(f32, 1 << 24) + 1 == 1 << 24); +} + +test "f64 at compile time is lossy" { + try expect(@as(f64, 1 << 53) + 1 == 1 << 53); +} + +test { + comptime try expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192); +} diff --git a/test/behavior/eval_stage1.zig b/test/behavior/eval_stage1.zig index c78d02c85e..2f9f33cfc5 100644 --- a/test/behavior/eval_stage1.zig +++ b/test/behavior/eval_stage1.zig @@ -114,22 +114,10 @@ test "float literal at compile time not lossy" { try expect(9007199254740992.0 + 1.0 == 9007199254740993.0); } -test "f32 at compile time is lossy" { - try expect(@as(f32, 1 << 24) + 1 == 1 << 24); -} - -test "f64 at compile time is lossy" { - try expect(@as(f64, 1 << 53) + 1 == 1 << 53); -} - test "f128 at compile time is lossy" { try expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0); } -test { - comptime try expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192); -} - pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type { _ = field_name; return struct { |
