Liste des Groupes | Revenir à cl c |
Thiago Adams <thiago.adams@gmail.com> writes:Thanks.Em 8/2/2024 10:25 PM, Keith Thompson escreveu:Wraparound, or unsigned wraparound if you want to be a little moreThiago Adams <thiago.adams@gmail.com> writes:>
[...]I am doing experiments with constexpr. What happens with overflow inYour first example fails due to signed integer overflow. Your
compile time? The answer is not so clear. Sometimes it does not
compile and sometimes it works as in runtime.
second
example is well defined because there is no such thing as unsigned
integer overflow.
I need a new name other than overflow.
precise.
C23 adds this entry to the glossary (3.28):
wraparound
the process by which a value is reduced modulo 2^N, where N is the
width of the resulting type
The standard uses a superscript, which I can't easily reproduce here.
I hope it's sufficiently obvious that I'm not using ^ to mean bitwise xor.
N3220 6.2.5p11 (same or similar wording appears in earlier editions) :
A computation involving unsigned operands can never produce an
overflow, because arithmetic for the unsigned type is performed
modulo 2^N.
The expressionRight. The subexpression ULLONG_MAX*ULLONG_MAX in infinite precision
>
ULLONG_MAX*ULLONG_MAX/ULLONG_MAX/ULLONG_MAX
>
has the result 1 if calculated with infinite precision.
>
But the calculated value here is 0
would be 340282366920938463426481119284349108225 in infinite precision,
but assuming 64-bit unsigned long long the actual result is that value
modulo 2^64, or 1. Dividing 1 by ULLONG_MAX yields 0 (since integer
division truncates); dividing again by ULLONG_MAX yields 0 again.
The reduction modulo 2^64 happens on each arithmitic operation (here one
multiplication and two divisions), not on the expression as a whole.
Since ULLONG_MAX*ULLONG_MAX is 1 (more precisely 1ull), the expression
ULLONG_MAX*ULLONG_MAX/ULLONG_MAX/ULLONG_MAX
is equivalent to
1ull/ULLONG_MAX/ULLONG_MAX
#include <stdio.h>
>
int main()
{
constexpr unsigned long long ULLONG_MAX = 18446744073709551615;
constexpr unsigned long long r =
ULLONG_MAX*ULLONG_MAX/ULLONG_MAX/ULLONG_MAX;
printf("%llu", r);
}
Les messages affichés proviennent d'usenet.