Index 0: Intended or Bug?


fn main() {
    let lis1 = [0000, 1111, 2222];

    
    println!("{:?}, {:?}, {:?}", lis1[0], lis1[1], lis1[2]);
}

The output: 0, 1111, 2222 (for index 0 a single 0, instead of the expected 0000, is the output)

Is this supposed to work like this?

The number zero is the number zero no matter how it’s written. The program can’t memorize how it was originally written in the source code because the string "0000" doesn’t even exist at runtime.

4 Likes

Yes, this is expected behavior. There is no such thing as number 0000 when generally speaking.

Implied type for numbers in lis1 is i32, and 0000 corresponds to 0, just like e.g. 000004 to 4, etc.

On the other hand, you may want to print/write number with specific number of leading zeroes naturally.
This can be done e.g. like this:

println!("{:04}", lis1[0]);

-> print first element from list, with leading 0's, 4 digits in total. You can see many details/options here.

As another example: println!("{}", 2 - 2); shall print 0, and not 2 - 2. It is very important to distinguish the representation of a number / quantity with the quantity / value itself. You can use multiple representations for the "null quantity", such as 0, 0000, 2 - 2 (this one is technically (the representation of) a computation, but that can be viewed as a representation as well (e.g., how are fractions (such as 1/3) represented, if not as a division?)), 0b0 (binary representation), 0x0 (hex representation). Be it as it may, the machine will end up with a value, represented / stored in its own machine format (e.g., 0b0000_0000__0000_0000__0000_0000__0000_0000_i32 in your case), and that value has a canonical representation, which the {}-Display (and {:?}-Debug) implementation uses, and in this instance such representation can even be tweaked. If you want 4-wide representations, using 0 to pad it, you can use {:04} (or {:04?}).

let s = format!("\
    `{0:}`\n\
    4-wide, ` `-padded, right-aligned:\n\
    `{0: >4}` shortened as `{0:4}`\n\
    4-wide, ` `-padded, centered:\n\
    `{0: ^4}`\n\
    4-wide, ` `-padded, left-aligned:\n\
    `{0: <4}`\n\
    \n\
    4-wide, `0`-padded, right-aligned:\n\
    `{0:0>4}` shortened as `{:04}`\n\
    etc.
    `{0:0^4}`\n\
    `{0:0<4}`\n\
    \n\
    Hex (with `0x` prefix):\n\
    `{0:#x}`\n\
    Binary (with `0x` prefix):\n\
    `{0:#b}`\n\
", 0);
assert_eq!(s, "\
`0`
4-wide, ` `-padded, right-aligned:
`   0` shortened as `   0`
4-wide, ` `-padded, centered:
` 0  `
4-wide, ` `-padded, left-aligned:
`0   `

4-wide, `0`-padded, right-aligned:
`0000` shortened as `0000`
etc.
    `0000`
`0000`

Hex (with `0x` prefix):
`0x0`
Binary (with `0x` prefix):
`0b0`
");
4 Likes

three layers of parentheses? :sweat_smile: :sweat_smile:

I mean I appreciate the fact that you haven't missed any closing parentheses, but when reading this I almost assumed you did untill I reached the final “))

8 Likes

:laughing: :sweat_smile:

You've gotten some great answers. I'd also add that there often values that look numerical but are better represented as strings. The fact that you care about the number of leading zeros suggests this might be your case. Phone numbers, and probably zipcodes are good examples.

9 Likes

My social security number begins with a 0. In the early days of computerizing stuff (I'm really old.), I often got an "Invalid SSN" error for exactly the reason pointed out here. It's a string, not 3 numbers.

Yep.

The important question is: "Are you doing math on it?"

If the answer is no, as in the case of SSN's, phone numbers, zip codes, and id numbers of most kinds, then what you really want is a string, not a number. A good example is when those zip codes are expanded to postal codes outside the U.S. and you find that letters are used.

1 Like

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.