-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
always allow integer comparison operations no matter the bit width, signedness, or comptime-ness of operands #2133
Comments
I disagree for the same reason all other operators do not implicitly cast. consider:
what is the expected value of |
OK, then I will just fix all the types, and convert |
actualy, those aren't that useful to bit functions. so nothing |
@tgschultz See my PR #3001 |
I think In Zig integers represent their mathematical values. There are a few design decisions that reflect this:
Further we already have precedence for relaxing type errors when the value is comptime known: const a: i64 = 10;
const b: u8 = a; //ok |
This test case already passes: comptime expect(255 > -1); This test case is accepted: comptime expect(u8(255) > i8(-1)); This test case is not accepted: const b = -u8(1) < i8(1); // error: invalid negation type: 'u8' |
@andrewrk so the comparison is allowed but only if the values are comptime known? That seems to make sense with the existing automatic comptime coercion allowed. Sorry if that was obvious, but I only just noticed that the title of the issue changed :-( Should that last test case pass? |
Is this also accepted for runtime values? |
If one of the operands is runtime known, then the comptime operand is casted to the type of the runtime operand. var a: u8 = 255;
const b: i8 = 10;
expect(a > b); // OK
const c: u8 = 255;
var d: i8 = 10;
expect(c > d); // error. cannot cast 255 to i8 another case: if the operation can be comptime known without any casting, it also works: var a: u8 = 255;
const b: i8 = -10;
comptime expect(a > b); // OK |
This can also work if both operands are runtime. |
Another use case of this: pub fn emitNumber(
self: *Self,
/// An integer, float, or `std.math.BigInt`. Emitted as a bare number if it fits losslessly
/// in a IEEE 754 double float, otherwise emitted as a string to the full precision.
value: var,
) !void {
assert(self.state[self.state_index] == State.Value);
switch (@typeInfo(@typeOf(value))) {
.Int => if (value < 4503599627370496 and value > -4503599627370496) {
try self.stream.print("{}", value);
self.popState();
return;
},
.Float => if (@floatCast(f64, value) == value) {
try self.stream.print("{}", value);
self.popState();
return;
},
else => {},
}
try self.stream.print("\"{}\"", value);
self.popState();
}
|
It is a deviation from C, but I think we should consider making this the behavior of the operators. See ziglang#2133
@shawnl looks like I did not understand the point of this proposal before; I do now, and it is planned. |
It is a deviation from C, but I think we should consider making this the behavior of the operators. See #2133
This should compile:
We should also consider and either accept, or explicitly reject (document) this:
The second case obeys our documented operator precedence, but in a very naïve implementation would need a i9 type here. I think this should be supported. If so, this support should to be explicitly documented by an example in the docs.
Supporting this is needed in order to make
math.minInt
andmath.maxInt
returnT
rather thancomptime_int
, which is desired by all the bit-manipulation intrinsics, as these return values have a fixed-length, unlikecomptime_int
.The text was updated successfully, but these errors were encountered: