mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
stage2: implement big int to float conversion
This commit is contained in:
parent
4cb5fed10b
commit
c8ded2f9c9
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user