Hacker News new | ask | show | jobs
by uecker 520 days ago
I am actually ok with the conversions and C and think they are quite convenient. Unsigned in C is modular. I am not sure what you mean by the "latest C standards specify". This did not change. I also do not understand what you mean by the "implicit cast of unsigned are those of non-negative numbers". This seems wrong. If you convert to a larger unsigned type, the value is unchanged and if you convert to a smaller, it is reduced modulo.
1 comments

In older C standards, the overflow of unsigned numbers was undefined.

In recent C standards, it has been defined that unsigned numbers behave with respect to the arithmetic operations as modular numbers, which never overflow.

The implicit casts of C unsigned numbers are from narrower to wider types, e.g. from "unsigned short" to "unsigned" or from "unsigned" to "unsigned long".

These implicit casts are correct for non-negative numbers, because all values that can be represented as e.g. "unsigned short" are included among those represented by "unsigned" and they are preserved by the implicit casts.

However, these implicit casts are incorrect for modular numbers, because they attempt to compute the inverse of a non-invertible function.

For instance, if you have an "unsigned char" that is a modular number with the value "3", it is incorrect to convert it to an "unsigned short" modular number with the value "3", because the same "unsigned char" "3" corresponds also to 255 other "unsigned short" values, i.e. to 259, 515, 781, 1027 and so on.

If you have some very weird reason when you want to convert a number modulo 256 to a number modulo 65536 by choosing a certain number among those with the same residue modulo 256, then you must do this explicitly, because it is not an information-preserving conversion.

If on the other hand you interpret a C "unsigned" as a non-negative number, then the implicit casts are OK, but you must add everywhere explicit checks for unsigned overflow around the arithmetic operations, otherwise you will obtain erroneous results.

The C89 standard has "A computation involving unsigned operands can never overflou. because a result that cannot be represented b! the resulting unsigned integer type is reduced modulo the number that is one greater thnn the largest value that can be represented by the resulting unsipned integer type" (OCR errors) You can finde a copy here: https://web.archive.org/web/20200909074736if_/https://www.pd...

Mathematically, there is no clearly defined way how one would have to map from one residue system in modular arithmetic to the next, so there is no "correct" or "incorrect" way. Mapping to the smallest integer in the equivalency class makes a lot of sense though, as it maps corresponding integers to itself when going to a larger type and and the reverse operation is then the inverse, and this is exactly what C does.