# Arithmetic operations on char

**URL:** https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564
**Category:** libs
**Created:** [October 14, 2022, 8:39pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564 "2022-10-14T20:39:33Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![GKFX](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gkfx/32/9508_2.png) [@GKFX](https://internals.rust-lang.org/u/GKFX)
#### Post date: [October 14, 2022, 8:39pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564/1 "2022-10-14T20:39:33Z")

</div>

`char` is an unsigned 32-bit integer with restricted range. However to actually do any sort of arithmetic on it you have to cast it to `u32`. I think this restriction should be lifted.

If you do arithmetic on a `char`, you still then have a 32-bit value, it's just no longer (necessarily) in the approved range: it is now a plain `u32`. So the standard library could usefully implement `Add<u32>`, `Sub<u32>`, `BitOr<u32>`, etc on char as below.

```rust
impl Add<u32> for char {
    type Output = u32;
    fn add(self, other: u32) { self as u32 + other }
}

```

Currently you have to do all the casting yourself which is needlessly verbose and also doesn't constrain you to u32; you can accidentally cast to u16 or u8 (etc) which is likely to lead to incorrect results. Implementing the standard arithmetic traits to allow char + u32 = u32 would both condense code and avoid that possible error.

For similar reasons, I would implement `PartialOrd<u32>` for `char`.

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [October 14, 2022, 8:46pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564/2 "2022-10-14T20:46:19Z")

</div>

Can you say _why_ you want to do arithmetic on a `char`? What are you doing that this is so common to be worth supporting without the cast?

Note that they _are_ iterable in ranges, now, so `'a'..='z'` works for that without ever needing to type `+ 1`.

> [@GKFX](#):
>
> you can accidentally cast to u16 or u8 (etc) which is likely to lead to incorrect results

There's no automatic widening, though.

So if you do `(u16)c + 10`, you'll then need another cast in order to [`from_u32`](https://doc.rust-lang.org/std/primitive.char.html#method.from_u32) it back into a `char`, which is a great opportunity to realize that you didn't want a `u16` in the first place.

---

<div class="post-metadata">

### Author: ![GKFX](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gkfx/32/9508_2.png) [@GKFX](https://internals.rust-lang.org/u/GKFX)
#### Post date: [October 14, 2022, 8:52pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564/3 "2022-10-14T20:52:25Z")

</div>

This was prompted by [Make is\_ascii\_hexdigit branchless by GKFX · Pull Request #103024 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/pull/103024/files), where I bitwise-or a character with `0x20` to convert ASCII uppercase to lowercase. In that example you would get an incorrect but compiling function by incorrectly specifying `u16` in place of `u32`.

---

<div class="post-metadata">

### Author: ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)
#### Post date: [October 14, 2022, 9:48pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564/4 "2022-10-14T21:48:24Z")

</div>

Instead of `as u32`, you can use `u32::from(char)`. `From<char>` is only implemented for `u32` and larger, so you're protected from accidentally using a smaller type.

---

<div class="post-metadata">

### Author: ![nacaclanga](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nacaclanga/32/7461_2.png) [@nacaclanga](https://internals.rust-lang.org/u/nacaclanga)
#### Post date: [October 19, 2022, 2:51pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564/5 "2022-10-19T14:51:25Z")

</div>

> [@GKFX](#):
>
> `char` is an unsigned 32-bit integer with restricted range.

I feel like this definition is wrong. `char` is a datatype describing an Unicode Scalar Value. These just happen to have a bijective mapping to a subset of unsigned 32-bit integers, which is used to store them in memory. `char` is not ment as a general integer type. (Similar to very large fieldless enums.)

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [January 17, 2023, 2:51pm UTC](https://internals.rust-lang.org/t/arithmetic-operations-on-char/17564/6 "2023-01-17T14:51:30Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
