Skip to content

Commit 561fdd0

Browse files
authored
Merge pull request #24188 from mlugg/intfromfloat-safety
Absorb std.math.big.rational logic into std.math.big.int; fix `@intFromFloat` safety check
2 parents 080ee25 + e498d8d commit 561fdd0

39 files changed

+1341
-1082
lines changed

lib/compiler/aro/aro/Value.zig

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -148,35 +148,25 @@ pub fn floatToInt(v: *Value, dest_ty: Type, comp: *Compilation) !FloatToIntChang
148148
return .out_of_range;
149149
}
150150

151-
const had_fraction = @rem(float_val, 1) != 0;
152-
const is_negative = std.math.signbit(float_val);
153-
const floored = @floor(@abs(float_val));
154-
155-
var rational = try std.math.big.Rational.init(comp.gpa);
156-
defer rational.deinit();
157-
rational.setFloat(f128, floored) catch |err| switch (err) {
158-
error.NonFiniteFloat => {
159-
v.* = .{};
160-
return .overflow;
161-
},
162-
error.OutOfMemory => return error.OutOfMemory,
163-
};
164-
165-
// The float is reduced in rational.setFloat, so we assert that denominator is equal to one
166-
const big_one = BigIntConst{ .limbs = &.{1}, .positive = true };
167-
assert(rational.q.toConst().eqlAbs(big_one));
168-
169-
if (is_negative) {
170-
rational.negate();
171-
}
172-
173151
const signedness = dest_ty.signedness(comp);
174152
const bits: usize = @intCast(dest_ty.bitSizeof(comp).?);
175153

176-
// rational.p.truncate(rational.p.toConst(), signedness: Signedness, bit_count: usize)
177-
const fits = rational.p.fitsInTwosComp(signedness, bits);
178-
v.* = try intern(comp, .{ .int = .{ .big_int = rational.p.toConst() } });
179-
try rational.p.truncate(&rational.p, signedness, bits);
154+
var big_int: std.math.big.int.Mutable = .{
155+
.limbs = try comp.gpa.alloc(std.math.big.Limb, @max(
156+
std.math.big.int.calcLimbLen(float_val),
157+
std.math.big.int.calcTwosCompLimbCount(bits),
158+
)),
159+
.len = undefined,
160+
.positive = undefined,
161+
};
162+
const had_fraction = switch (big_int.setFloat(float_val, .trunc)) {
163+
.inexact => true,
164+
.exact => false,
165+
};
166+
167+
const fits = big_int.toConst().fitsInTwosComp(signedness, bits);
168+
v.* = try intern(comp, .{ .int = .{ .big_int = big_int.toConst() } });
169+
big_int.truncate(big_int.toConst(), signedness, bits);
180170

181171
if (!was_zero and v.isZero(comp)) return .nonzero_to_zero;
182172
if (!fits) return .out_of_range;

lib/std/math.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub const rad_per_deg = 0.017453292519943295769236907684886127134428718885417254
4545
/// 180.0/pi
4646
pub const deg_per_rad = 57.295779513082320876798154814105170332405472466564321549160243861;
4747

48+
pub const FloatRepr = float.FloatRepr;
4849
pub const floatExponentBits = float.floatExponentBits;
4950
pub const floatMantissaBits = float.floatMantissaBits;
5051
pub const floatFractionalBits = float.floatFractionalBits;

lib/std/math/big.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const std = @import("../std.zig");
22
const assert = std.debug.assert;
33

4-
pub const Rational = @import("big/rational.zig").Rational;
54
pub const int = @import("big/int.zig");
65
pub const Limb = usize;
76
const limb_info = @typeInfo(Limb).int;
@@ -18,7 +17,6 @@ comptime {
1817

1918
test {
2019
_ = int;
21-
_ = Rational;
2220
_ = Limb;
2321
_ = SignedLimb;
2422
_ = DoubleLimb;

0 commit comments

Comments
 (0)