Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between casting to `i32` from `usize` versus the other way?

Tags:

rust

I am making a function that makes a array of size n random numbers but my comparison for the while throws an error.

while ar.len() as i32 < size { }

Complains with: expected one of !, (, +, ,, ::, <, or >, found {.

If I remove the as i32 it complains with mismatch types and if I add a as usize to the size variable then it doesn't complain.

like image 444
Sebastian Avatar asked Sep 21 '16 17:09

Sebastian


People also ask

Why can't I cast a Usize to I32?

Casting a usize to a i32 thus will operate differently depending on what type of machine you are running on. The error message you get is because the code you've tried isn't syntactically correct, and the compiler isn't giving a good error message.

What is the difference between I32 and 32 bit Usize?

A usize is defined to be a "pointer-sized integer", which is usually the native size of the machine. On a 64-bit x64 processor, that means a usize is 64 bits, and on a 32-bit x86 processor, it will be 32 bits. Casting a usize to a i32 thus will operate differently depending on what type of machine you are running on.

What is the difference between type conversion and casting in C?

Whereas in type conversion, there is no need for a casting operator. 4. In typing casting, the destination data type may be smaller than the source data type, when converting the data type to another data type. Whereas in type conversion, the destination data type can’t be smaller than source data type.

What is the difference between const and Usize in C++?

const: unstable· source fn div(self, other: NonZeroUsize) -> usize This operation rounds towards zero, truncating any fractional part of the exact result, and cannot panic. type Output= usize The resulting type after applying the /operator. const: unstable· source impl<'a> Div<usize> for &'a usize type Output= <usizeas Div<usize>>::Output


2 Answers

When you cast from a smaller-sized type to a larger one, you won't lose any data, but the data will now take up more space.

When you cast from a larger-sized type to a smaller one, you might lose some of your data, but the data will take up less space.

Pretend I have a box of size 1 that can hold the numbers 0 to 9 and another box of size 2 that can hold the numbers 0 to 99.

If I want to store the number 7; both boxes will work, but I will have space left over if I use the larger box. I could move the value from the smaller box to the larger box without any trouble.

If I want to store the number 42; only one box can fit the number: the larger one. If I try to take the number and cram it in the smaller box, something will be lost, usually the upper parts of the number. In this case, my 42 would be transformed into a 2! Oops!

In addition, signed and unsigned plays a role; when you cast between signed and unsigned numbers, you might be incorrectly interpreting the value, as a number like -1 becomes 255!

See also:

  • How do I convert between numeric types safely and idiomatically?


In this particular case, it's a bit more complicated. A usize is defined to be a "pointer-sized integer", which is usually the native size of the machine. On a 64-bit x64 processor, that means a usize is 64 bits, and on a 32-bit x86 processor, it will be 32 bits.

Casting a usize to a i32 thus will operate differently depending on what type of machine you are running on.


The error message you get is because the code you've tried isn't syntactically correct, and the compiler isn't giving a good error message.

You really want to type

while (ar.len() as i32) < size { }

The parenthesis will help the precedence be properly applied.

To be on the safe side, I'd cast to the larger value:

while ar.len() < size as usize { }

See also:

  • How do I convert a usize to a u32 using TryFrom?
  • How to idiomatically convert between u32 and usize?
  • Why is type conversion from u64 to usize allowed using `as` but not `From`?
like image 144
Shepmaster Avatar answered Oct 23 '22 10:10

Shepmaster


It seems that your size is of type i32. You either need parentheses:

while (ar.len() as i32) < size { }

or cast size to usize:

while ar.len() < size as usize { }

as len() returns a usize and the types on both sides of the comparison need to match. You need the parentheses in the first case so that the < operator doesn't try to compare i32 with size but rather ar.len() as i32 with size which is your intention.

like image 4
ljedrz Avatar answered Oct 23 '22 12:10

ljedrz