4 ms·
Yes, it is, for 32-bit floats. However, most of the time you don't need to specify that, because it will be inferred from the context. (And if it isn't you can
by GolDDranks 9y ago
Yes, it is, for 32-bit floats. However, most of the time you don't need to specify that, because it will be inferred from the context. (And if it isn't you can introduce hints like `let growth_rate: f32 = 50.0/140.0`) Also, Rust supports having _ anywhere in number literals. Some may argue that it makes things even noisier, but it helps to separate the suffix from the value itself: `100.0_f32`.
- slavik81 9y agoVery nice. As you say, it doesn't just cast at the end, but actually uses the type through the whole calculation! To illustrate the difference: Rust: fn main() { let a: f32 = 1e7 + 0.5 + 0.5; let b: f32 = 1e7f32 + 0.5f32 + 0.5f32; println!("{}", a==c); // true } C: #include <stdio.h> int main() { float a = 1e7 + 0.5 + 0.5; float b = 1e7f + 0.5f + 0.5f; printf("%s\n", a==b ? "true" : "false"); // false } That's awesome. I'm totally fine with an annoying suffix like f32 if I never actually need to use it. While f might be a nicer suffice than f32, no suffix is even better.
- steveklabnik 9y agoYou often don't need it at all; fn foo(x: f32) { println!("{}", x); } fn main() { let x = 5.0; foo(x); } It will look at the signature for foo, and infer that x must be f32.
- Arkanosis 9y agoWhoa! Isn't this kind of inference dangerous? It seems that whichever call comes first is used to infer the type, so a single added line of code can change the type of a variable… fn foo32(x: f32) { println!("{}", x); } fn foo64(x: f64) { println!("{}", x); } fn bar64() { let x = 5.0; // f64 foo64(x); foo32(x); } fn bar32() { let x = 5.0; // f32, not f64 foo32(x); foo64(x); }
- dbaupp 9y agoRust doesn't have coercions like C, so both of those fail to compile because using x: f64 with foo32 is an error for the first one and similarly x: f32 with foo64 for the second.
- kibwen 9y agoThat code doesn't compile. :) If you're ever curious about something like this, feel free to use the online playground, like so: https://play.rust-lang.org/?gist=c3c93fb796d5fa79f829baa3dece0489&version=stable https://play.rust-lang.org/?gist=c3c93fb796d5fa79f829baa3dec... Here's the compiler error that you'd get: error[E0308]: mismatched types --> src/main.rs:7:13 | 7 | foo32(x); | ^ expected f32, found f64 error[E0308]: mismatched types --> src/main.rs:13:13 | 13 | foo64(x); | ^ expected f64, found f32
- irishsultan 9y agoIn addition to what the others said about this not working you can get this to work by providing a conversion to either of the calls, so this works: fn foo32(x: f32) { println!("{}", x); } fn foo64(x: f64) { println!("{}", x); } fn bar64() { let x = 5.0; // f64 foo64(x); foo32(x as f32); } fn bar32() { let x = 5.0; // f32, not f64 foo32(x); foo64(x as f64); }
- kbenson 9y ago> While f might be a nicer suffice than f32, no suffix is even better. Well, isn't float in C and C++ platform dependent, and just usually 4 bytes on common platforms? I like the idea of being explicit in the storage type, even if it's slightly more verbose.
- knz42 9y agoNo. ISO C has standardized "float" to 32 bits and "double" to 64 bits. The one that's platform-dependent is "long double".
- ComputerGuru 9y agoAnd, oxymoronically, plain, old long. In particular, everything but MSVC treats long as 64 bits, but MSVC treats it as 32 bits for backwards compatibility. However, I haven't used int or long or long long in ten years or so. Thanks to stdint.h support finally making its way to all platforms, it's exclusively sized types like int32_t and uint16_t for me.
- slavik81 9y agoI might otherwise agree with you, but I find it hard to read when extra numbers are interspersed with the numbers that actually part of the calculation. I feel the readability matters more than the explicitness.
- ComputerGuru 9y agoThe reason this works the way it does is that rust does not provide any cross-type arithmetic operators; as in you can't multiply a signed int and unsigned int or a float and an u8 without casting one of them to the same type as the other. That means for the example you posted works is because the only valid operation that line of code can be resolved to as-is would be the case where all untyped values are inferred to be float by the inference engine.