Hallo zusammen,
ich habe mal wieder ein Integer-Denkproblem. Wie immer wäre mir eine
Quelle (Link/Buchnennung) sogar noch lieber als die direkte Lösung.
Ich habe eine Funktion, die eine zur Compile-Zeit bekannte Konstante
durch eine Variable dividiert:
1 | #define MARKER 16777213ULL
|
2 |
|
3 |
|
4 | uint32_t overflowVal(uint32_t divisor)
|
5 | {
|
6 | uint64_t marker = MARKER;
|
7 | uint64_t overflow = marker * marker/(2*divisor);
|
8 | const uint64_t threshold = INT32_MAX/2;
|
9 |
|
10 | assert( overflow <= threshold );
|
11 |
|
12 | return overflow;
|
13 | }
|
Für den Divisor gibt es einen kleinstmöglichen erlaubten Wert (>0), den
ich exakt berechnen will. Dass es toll ist, wenn das zur Compilezeit
geschieht, ist jetzt erst einmal nur am Rande interessant.
Der naive Ansatz:
1 | uint32_t minDivider(void)
|
2 | {
|
3 | uint64_t marker = MARKER;
|
4 | const uint64_t threshold = INT32_MAX/2;
|
5 |
|
6 | uint32_t dMin = marker*marker/(2*threshold);
|
7 | return dMin;
|
8 | }
|
hat einen Eins-daneben-Fehler für alle bisher getesteten Werte von
"Marker".
Wie kann ich den kleinsten Divisor d, bei dem d-1 einen unerlaubten
Überlauf liefert und d im gültigen Bereich liegt, für beliebige Werte
des Dividenden berechnen?
Viele Grüße
W.T.