Whether to use type isize or i32, fsize or f64, usize or u32

I'm not sure I'm proposing anything really. That quote from my old boss comes from 1982 or so. It was a very different world. Slow processors, no float hardware, at least not on the systems I worked on, small memories, etc.

I have though about that quote over the decades. It is the case that at that time, on that system, for the problems we had, (it was a military, three dimensional phased array radar system by the way) floating point was not actually required. I have found that to be true on many projects since.

I think what it is really about is that one has to understand the problem one is trying to solve. What number ranges are involved, what accuracy do you really need, what accuracy do you actually have, what is an efficient way of storing and processing it all. And so on. Verses a tendency to brush all those problems under the carpet by using floats. Which works fine for most people most of the time now a days and costs almost nothing in performance and memory is copious.

3 Likes

Fixed point is still a rational data type rather than an integral one for this purpose. Fixed point is just an integer with an odd unit w.r.t. addition/subtraction, as well as multiplication/division with unitless pure count integers, but not for multiplication/division between fixed point numbers (even with the same fixed point), so it's a rational data format, not just a weird integral unit.

We agree on this point, actually — fixed point is often a better choice (and perhaps more often than not), but floating point is a very convenient format that works "well enough" for all but specialized cases.

If you're doing anything to the data other than storage, you need to track significant figures / error bounds separately anyway.

It's a convenience thing, honestly quite similar to floating point versus fixed point. The sign can be attached as part of the type (perhaps implicit), or it can be part of the data. I agree that (uNN, bool) is very very rarely what you want.

... two comparisons, just like with signed types? e.g. given n: u32, 273 <= n && n <= 373. If reducing to a single comparison, you want wrapping math and unsigned comparison, not signed math. e.g. n.wrapping_sub(273) <= 100. (The optimizer will certainly do this transformation for you if it's beneficial.)

All sensors I've ever worked directly with output an unsigned integer, where it's an interpolation between whatever the min and max possible readings are. I've used a couple behind an SDK, and every SDK I've used converts the reading to a floating point value in standard units.

I don't doubt some exist where they report with two's compliment, but I've not used any. Though I've not used beyond single digits of sensors, to be fair.

1 Like

a decent example is the HX711 (datasheet pdf) which is an ADC designed for Weigh Scales with a 24-bit 2's complement output (aka. i24).

1 Like

The integers isize, usize are for when you are counting memory. (indexing vec or array for example)
The integers u32, i32, u64, etc are for when you are doing anything else.

With the u8, u32, style you can specify how many bits the variable holds.

With usize, you get a variable with enough bits big enough to point to any location in memory.

But can someone explain how isize can be big enough if it is same size as usize? Both isize and usize have the same descriptive text.

The size of this primitive is how many bytes it takes to reference any location in memory. For example, on a 32 bit target, this is 4 bytes and on a 64 bit target, this is 8 bytes.

Can isize point to a negative place?
How does an isize point to the upper half of memory?

The size types are supposed to have enough bits to represent a pointer. Depending on your memory mapping, some pointers might correspond to negative numbers if you use a signed type. The article Rust's Unsafe Pointer Types Need An Overhaul - Faultlore explains conversions between pointers and integers and why it might need to be overhauled in Rust.

Rust constrains allocations of nonzero-sized types to be less than the maximum isize and it doesn't make sense to compare pointers to different objects so this isn't really an issue: any offset you need fits into either type.

It's not a pointer, it's twos-complement integer (that happens to have the same number of bits as a pointer). It can represent the byte offset between any two pointers as a result.

"Why the isize limitations" (e.g. on allocation size) generally comes down to things like GEP as discussed in more depth in the article @user16251 linked.

Note that this does not mean it can store all differences between any two usizes, as that would require one extra bit.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.