3 ms·
> Implicit numeric conversion is terrible. It's bad if it alters values (e.g. rounding). Promotion from one number representation to another (as long as it pre
by titzer 1y ago
> Implicit numeric conversion is terrible.
It's bad if it alters values (e.g. rounding). Promotion from one number representation to another (as long as it preserves values) isn't bad. This is trickier than it might seem, but Virgil has a good take on this (https://github.com/titzer/virgil/blob/master/doc/tutorial/Numbers.md https://github.com/titzer/virgil/blob/master/doc/tutorial/Nu...). Essentially, it only implicitly promotes values in ways that don't lose numeric information and thus are always reversible.
In the example, Virgil won't let you pass "1000.00" to an integer argument, but will let you pass "100" to the double argument.
- plus 1y agoAside from the obvious bit size changes (e.g. i8 -> i16 -> i32 -> i64, or f32 -> f64), there is no "hierarchy" of types. Not all ints are representable as floats. u64 can represent up to 2^64 - 1, but f64 can only represent up to 2^53 with integer-level precision. This issue may be subtle, but Rust is all about preventing subtle footguns, so it does not let you automatically "promote" integers to float - you must be explicit (though usually all you need is an `as f64` to convert).
- mananaysiempre 1y ago> Aside from the obvious bit size changes (e.g. i8 -> i16 -> i32 -> i64, or f32 -> f64), there is no "hierarchy" of types. Depends on what you want from such a hierarchy, of course, but there is for example an injection i32 -> f64 (and if you consider the i32 operations to be undefined on overflow, then it’s also a homomorphism wrt addition and multiplication). For a more general view, various Schemes’ takes on the “numeric tower” are informative.
- titzer 1y agoVirgil allows the maximum amount of implicit int->float injections that don't change values and allows casts (in both directions) that check if rounding altered a value. It thus guarantees that promotions and (successful) casts can't alter program behavior. Given any number in representation R, promotion or casting to type N and then casting back to R will return the same value. Even for NaNs with payloads (which can happen with float <-> double).
- titzer 1y agoYep, Virgil only implicitly promotes integers to float when rounding won't change the value. // OK implicit promotions def x1: i20; def f1: float = x1; def x2: i21; def f2: float = x2; def x3: i22; def f3: float = x3; def x4: i23; def f4: float = x4; // compile error! def x5: i24; def f5: float = x5; // requires rounding This also applies to casts, which are dynamically checked. // runtime error if rounding alters value def x5: i24; def f5: float = float.!(x5);
- dzaima 1y agoEven that is somewhat bad, e.g. it means you miss "some_u64 = some_u32 * 8" losing bits due to promoting after the arith op, not before.
- renox 1y agoI disagree: when you use floats, you implicitly accept the precision loss/roundings that comes with using floats.. IMHO int to float implicit conversion is fine as long as you have explicit float to int conversion.