./. schrieb:>> Dividieren>> Wohl kaum.
1 mod 2 = 1
2 mod 2 = 0
3 mod 2 = 1
4 mod 2 = 0
Doch, also das ist ziemlich einfach zum schreiben und (für mich)
verständlicher als obige Bitmanipulation. Dass es wahrscheinlich länger
zum ausführen braucht sollte bei einem PC-Programm bei solchem Kleinkram
eher weniger Probleme machen.
Jan H. schrieb:> Dass es wahrscheinlich länger zum ausführen braucht
Tut es nur bei einem wirklich herausragend lausigen C-Compiler. Jeder
andere erkennt, worum es bei % 2 geht.
Was ist eigentlich "einfacher" daran,
1
a%2
anstelle von
1
a&1
zu schreiben?
Die gleiche Anzahl von Zeichen, und beide Male ist das Sonderzeichen nur
mit der Shifttaste erreichbar.
Mir liegt es näher, eine mathematische Eigenschaft mit einer
mathematischen Funktion zu prüfen, statt mit einer, die auf einem
Zahlensystem basiert. Ist aber persönliche Vorliebe.
Jan H. schrieb:> Mir liegt es näher, eine mathematische Eigenschaft mit einer> mathematischen Funktion zu prüfen, statt mit einer, die auf einem> Zahlensystem basiert. Ist aber persönliche Vorliebe.
So ein Quatsch. Beides basiert auf den Eigenschaften des
zugrundeliegenden Zahlensystems. Das "2er" = bitoperation System deckt
die binäre Eigenschaft "gerade/ungerade" besser ab als das Zehnersystem.
Rufus Τ. F. schrieb:> Die gleiche Anzahl von Zeichen, und beide Male ist das Sonderzeichen nur> mit der Shifttaste erreichbar.
Das Ergebnis ist freilich verschieden, und folglich auch die
Implementierung, wenn negative Werte möglich sind. Bei & ist es +1 bei
ungeraden negativen Zahlen, bei % -1. Für den nackten Test ist das
natürlich egal.
Rufus Τ. F. schrieb:> Tut es nur bei einem wirklich herausragend lausigen C-Compiler.
Wozu du offenbar auch GCC zählst. ;-)
Der dividiert nämlich bei dessen meistgenutzer Optimierungsstufe -Os.
Weil kürzer.
Jan H. schrieb:> Mir liegt es näher, eine mathematische Eigenschaft mit einer> mathematischen Funktion zu prüfen, statt mit einer, die auf einem> Zahlensystem basiert.
Na dann:
1
#define iseven(a) (((a) / 2)*2 == (a))
:-)
Ich glaube, ich muß mal nachschauen, was der GCC da herausoptimiert.
A. K. schrieb:> % bei -Os: ldi r22,lo8(2)> ldi r23,0> rcall __divmodhi4> ret
Das sieht ja auf den ersten Blick aus wie ein Riesen-Unterschied. Aber
wie sieht __divmodhi4 aus? Wie lang ist die? Und dann vergleiche bitte
nochmal mit -O1...
?!? schrieb:> Das sieht ja auf den ersten Blick aus wie ein Riesen-Unterschied. Aber> wie sieht __divmodhi4 aus? Wie lang ist die?
Der Compiler berücksichtigt bei solchen Entscheidungen nur die Länge des
unmittelbar erzeugten Codes, nicht die Länge von dadurch herangezogenen
Laufzeitfunktionen.
Walter T. schrieb:> Sehr interessant die sehr unterschiedliche Optimierung.
Erschreckend, daß Compiler immer noch genau so strohdoof sind wie vor 30
Jahren (Optimierungsanalyse war meine Studienarbeit), aber grossmäulig
ständig mit angeblichen superneuen Spitzenoptimierungen angepriesen
werden.
A. K. schrieb:> Der Compiler berücksichtigt bei solchen Entscheidungen nur die Länge des> unmittelbar erzeugten Codes, nicht die Länge von dadurch herangezogenen> Laufzeitfunktionen.
Sorry, aber das verstehe ich jetzt nicht ganz. Heißt das, daß eine
aufgerufene Funktion mit z.B. 500 Zeilen Code vom Compiler als kürzer
angesehen wird, weil die eigentliche Funktion gar nicht mitgezählt wird,
sondern nur der Aufruf dieser Funktion?
Da hab ich bestimmt einen Denkfehler, aber ich habe deine Aussage so
verstanden. Korrigiere mich bitte!
Michael B. schrieb:> Erschreckend, daß Compiler immer noch genau so strohdoof sind wie vor 30> Jahren (Optimierungsanalyse war meine Studienarbeit), aber grossmäulig> ständig mit angeblichen superneuen Spitzenoptimierungen angepriesen> werden.
Sehr erschreckend, dass jemand, der Optimierungsanalyse als
Studienarbeit hatte, nicht erkennt, dass Optimierung auf Platz das Ziel
hat, kürzeren Code zu erzeugen. Wenn der Aufruf der Laufzeitfunktion
erheblich kürzer ist, dann ist das in diesem Sinn legitim.
gerade schrieb:> Jan H. schrieb:>> Mir liegt es näher, eine mathematische Eigenschaft mit einer>> mathematischen Funktion zu prüfen, statt mit einer, die auf einem>> Zahlensystem basiert. Ist aber persönliche Vorliebe.>> So ein Quatsch. Beides basiert auf den Eigenschaften des> zugrundeliegenden Zahlensystems.
Und dann versuch mal, binäre Operationen auf floating Point anzusetzen.
In modernen Sprachen ist nicht klar, daß Zahlen Integer sind.
Einfach hinschreiben, was man wirklich meint, und dann klapts in jeder
Sprache. Geht natürlich der Coolnessfaktor "ich weiß wie das Teil innen
funktioniert" verloren.
MfG Klaus
?!? schrieb:> Da hab ich bestimmt einen Denkfehler, aber ich habe deine Aussage so> verstanden. Korrigiere mich bitte!
Richtig erfasst. Nur weiss der Compiler an der Stelle, an der diese
Optimierung durchgeführt wird, nicht, wie gross die Laufzeitfunktion ist
und auch nicht, wie oft sie aufgerufen wird. Wird diese int/int Division
im gesamten Programm nur einmal verwendet, dann ist die Bilanz
ungünstig. Wird sie 1000x aufgerufen, dann liegt er aber sowas von
richtig.
Michael B. schrieb:> Erschreckend, daß Compiler immer noch genau so strohdoof sind wie vor 30> Jahren (Optimierungsanalyse war meine Studienarbeit), aber grossmäulig> ständig mit angeblichen superneuen Spitzenoptimierungen angepriesen> werden.
Anderer Test, anderer Code ;-)
1
intf(inta,intb,intc)
2
{
3
if(a%2)
4
returnb;
5
else
6
returnc;
7
}
mit -Os:
1
mov r25,r23
2
sbrc r24,0
3
rjmp .L2
4
mov r22,r20
5
mov r25,r21
6
.L2:
7
mov r24,r22
Es hängt schon ein wenig vom Kontext ab, was für Code produziert wird.
Ganz so blöd ist GCC nämlich auch wieder nicht. Bei meinem Testcode oben
hatte er keine Chance. Das hättest du als erklärter Kenner von Compilern
eigentlich erkennen müssen.
Klaus schrieb:> Einfach hinschreiben, was man wirklich meint, und dann klapts in jeder> Sprache.
Eben.
Ausnahmen bestätigen zwar die Regel, aber das sind dann meist
kompliziertere Fälle.
Im konkreten Beispiel klappt es jedenfalls ohne Verrenkungen:
Michael B. schrieb:> Erschreckend, daß Compiler immer noch genau so strohdoof sind wie vor 30> Jahren (Optimierungsanalyse war meine Studienarbeit),
Dann reich doch einfach mal einen entsprechenden Patch ein.
Kann ja für dich als Super-Duper-1337H4x00R nicht so schwer sein...
A. K. schrieb:> Da wird der Code aber viel umständlicher:
:-))
Wunderbar! Ein "C"-Programmierer mit Humor. Danke, daß Du das
Assembler-Resultat mit drangehangen hast, damit ich sehen konnte, wie Du
die 5
"beschützt" hast.
mfG Paul
Klaus schrieb:> Einfach hinschreiben, was man wirklich meint, und dann klapts in jeder> Sprache.
Du schreibst in beiden Fällen nicht hin, was du meinst.
Jan H. schrieb:> Mir liegt es näher, eine mathematische Eigenschaft mit einer> mathematischen Funktion zu prüfen, statt mit einer, die auf einem> Zahlensystem basiert. Ist aber persönliche Vorliebe.
Das kann aber beim Programmieren total in die Irre führen. Mathematisch
ist es korrekt (und zeitgemäss) zu fragen, ob die Zahl zur Menge der
geraden oder zur Menge der ungeraden Zahlen gehört. Blöd nur, dass beide
Mengen unendlich sind (was einen Mathematiker überhaupt nicht stört,
einen Computer aber schon).
Georg
Rolf M. schrieb:> Du schreibst in beiden Fällen nicht hin, was du meinst.
Die Modulo-Methode nutzt aber eine mathematische Eigenschaft der geraden
Zahlen und ist damit deutlich näher an der eigentlichen Fragestellung
als die Bit-Anguck-Methode, die die Art, in der Zahlen im Speicher
repräsentiert werden, ausnutzt und die Frage nur implizit beantwortet.
Tom schrieb:> als die Bit-Anguck-Methode, die die Art, in der Zahlen im Speicher> repräsentiert werden, ausnutzt und die Frage nur implizit beantwortet.
Sollte jemand mal auf die mittlerweile recht exotische Idee kommen,
Integers im Einerkomplement darzustellen, wird er die Bitvariante bei
negativen Werten nicht nutzen können. Es gab aber eine Zeit, da war
diese Darstellung nicht unüblich.
... schrieb:> Ich beglueckwuensche den Schreiber zu der mit Abstand dussligsten> Variante.
Ein Zeichen für absolute Phantasielosigkeit. Da ist noch deutlich mehr
drin:
A. K. schrieb:> Sehr erschreckend, dass jemand, der Optimierungsanalyse als> Studienarbeit hatte, nicht erkennt, dass Optimierung auf Platz das Ziel> hat, kürzeren Code zu erzeugen.
Und warum erzeugt der Compiler dann nicht den
andi r18,1
clr r19
?
Ist doch kurz, kürzer als alle beiden anderen.
ZehUndUnd schrieb:> Der Funktionsname 'isnoteven' dürfte aussagekräftiger sein.
Die Funktionsnamen sind sowieso ein interessanter Punkt. Als alter
Matlab-Nutzer wären mir als erstes die Namen "isodd"/"iseven"
eingefallen. Oben fiel auch schon der Name "odd" - das klingt für mich
deutlich C-mäßiger (da ein bischen kryptischer). Für den AVR wäre dann
noch eine Funktion "oddi8" oder "oddu8" fällig. Von Funktionen, die nur
direkt Flash-Konstanten unterstützen ("oddi8_P" und oddu8_P") würde ich
allerdings absehen.
Der langen Scherze kurzer Sinn:
Wie würde ein langjähriger C-Veteran eine solche Funktion überhaupt
nennen?
Michael B. schrieb:> Und warum erzeugt der Compiler dann nicht den> Ist doch kurz, kürzer als alle beiden anderen.
Ist kurz aber falsch. -3 % 2 ist -1, nicht +1. Und bei aller Liebe zu
Optimierung - es sollte schon das richtige Ergebnis rauskommen.
Mein Code verlangte nach dem Ergebnis von a % 2, Yalus aber nach dem von
(a % 2) != 0. Das ist der entscheidende Unterschied, der bei Yalu dem
Optimizer erlaubt, auf das Vorzeichen zu scheissen.
Walter T. schrieb:> Wie würde ein langjähriger C-Veteran eine solche Funktion überhaupt> nennen?
Für deine Varianten gefiele mir "isOdd" sehr gut, für beide.
Allein schon der sprachlichen Zweideutigkeit wegen. ;-)
A. K. schrieb:> Ist kurz aber falsch. -3 % 2 ist -1, nicht +1.
Spielt, bei einer Auswertung durch if, aber keine Rolle, und das
auszugucken sollte einen Compiler nicht überfordern.
Michael B. schrieb:> Spielt, bei einer Auswertung durch if, aber keine Rolle, und das> auszugucken sollte einen Compiler nicht überfordern.
Dummerweise war in meinem Code aber weit und breit kein "if" zu sehen.
Das war ein typischer Testcase einer einzelnen Operation. Minimiert auf
die Essenz, isoliert in einer entsprechenden Funktion. Da hat der
Compiler keinerlei Chance, irgendwas aus dem ihn nicht bekannten Kontext
zu erschliessen.
Hintergrund: Shifts/Maskierungen werden ziemlich regelmässig als
faktisch äquivalent zu div/mod mit Zweierpotenz gesehen. Das ist so
verbreitet, dass es manche dann erstaunt, wenn es dank möglicher
negativer Werte nicht so ist und es dann je nach Kontext und
Zielmaschine böse Laufzeitauswirkung hat (arm-gcc verhält sich anders).
Die Methode, Eigenschaften in einzelne Zwergfunktionen auszulagern, ist
nicht ganz so exotisch. Teils eine Stilfrage ist das bei C++ sehr
verbreitet, und nicht immer inlined.
Walter T. schrieb:> Die Funktionsnamen sind sowieso ein interessanter Punkt. Als alter> Matlab-Nutzer wären mir als erstes die Namen "isodd"/"iseven"> eingefallen. Oben fiel auch schon der Name "odd" - das klingt für mich> deutlich C-mäßiger (da ein bischen kryptischer). Für den AVR wäre dann> noch eine Funktion "oddi8" oder "oddu8" fällig. Von Funktionen, die nur> direkt Flash-Konstanten unterstützen ("oddi8_P" und oddu8_P") würde ich> allerdings absehen.>> Der langen Scherze kurzer Sinn:>> Wie würde ein langjähriger C-Veteran eine solche Funktion überhaupt> nennen?
Auf jeden Fall nicht iseven oder isodd, da diese Namen verboten sind.
Walter T. schrieb:> Für den AVR wäre dann> noch eine Funktion "oddi8" oder "oddu8" fällig.
Für die Zeit vor Weihnachen wünsche ich mir "odduFröhliche!"
mfG Paul
Rufus Τ. F. schrieb:> Rolf M. schrieb:>> Auf jeden Fall nicht iseven oder isodd, da diese Namen verboten sind.>> Durch wen?
Apple. Das i am Wortanfang ist ein eingetragenes Warenzeichen. Oder war
es Intel? iSeven ist doch deren leistungsfähigster Prozessor ;-)
Dussel schrieb:>>> Auf jeden Fall nicht iseven oder isodd, da diese Namen verboten sind.>>>> Durch wen?
Isnichwahr!
https://www.youtube.com/watch?v=r3LniM4pQ-A>> Für die Zeit vor Weihnachen wünsche ich mir "odduFröhliche!"A. K. schrieb:> Mit Umlaut?
Ach ja -das ist ja "C", das war in manchen Sachen als Kind schon anders.
;-)
mfG Paul
Dussel schrieb:> Rufus Τ. F. schrieb:>> Rolf M. schrieb:>>> Auf jeden Fall nicht iseven oder isodd, da diese Namen verboten sind.>>>> Durch wen?> Apple. Das i am Wortanfang ist ein eingetragenes Warenzeichen. Oder war> es Intel? iSeven ist doch deren leistungsfähigster Prozessor ;-)
D. h. man muss die Forumspfeifen mit Diot anreden?
ZehUndUnd schrieb:> D. h. man muss die Forumspfeifen mit Diot anreden?
Da Warenzeichen auf Produktbereiche bezogen sind, wär das nur der Fall,
wenn Apple das auch für den Bereich von (geistiger) Gesundheit
angemeldet hat, oder eine Verwechselbarkeit gegeben ist (mit der eigenen
Kundschaft?).
A. K. schrieb:> ZehUndUnd schrieb:>> D. h. man muss die Forumspfeifen mit Diot anreden?>> Da Warenzeichen auf Produktbereiche bezogen sind, wär das nur der Fall,> wenn Apple das auch für den Bereich von (geistiger) Gesundheit> angemeldet hat, oder eine Verwechselbarkeit mit der eigenen kundschaft> nicht auszuschlissen ist.
Ist aus deinen Ausführungen u. U. ein kleiner Vorbehalt gegenüber Apple
herauszulesen?
Bei allem Tanz um den Namen: Ich nehme also eine Integerzahl,
konvertiere sie in Text und prüfe ob die letzte Ziffer eine '1' ist.
"%i" formatiert Integer als eine ganz normale Dezimalzahl. Wo ist also
die Prüfung auf 3, 5, 7 und 9? Nich sind 40% aller Ergebnisse falsch!
ZehUndUnd schrieb:> Ist aus deinen Ausführungen u. U. ein kleiner Vorbehalt gegenüber Apple> herauszulesen?
Aber nicht doch! Ich freu mich nur auf ein diesbezügliches
Gerichtsverfahren. Weil ja irgendwo eine Verwechselungsmöglichkeit
bestehen müsste. Dafür kämen ja nur die Firmenmitarbeiter oder die
Kundschaft in Frage.
Rolf M. schrieb:> ISO C.
Ich habe ja durchaus versucht, irgendwas derartiges zu finden -- bitte
nenne doch mal die Stelle im Standard, die isodd/iseven verbietet.
Im Draft für C-99 tauchen weder isodd noch iseven auf, und das sieht im
Draft für C-11 (N1570) nicht anders aus.
POSIX reserviert einige Namen, damit gewisse Bibliotheksfunktionen
erweitert werden können. Damit es z.B. keine Kollisionen mit den
Funktionen in ctype.h (isalpha,isdigit usw) gibt, sollen z.B. keine
Namen mit "is" beginnen. Diese Einschränkung gibt es bei ISO-C selbst
m.W. nicht.
marco schrieb:> Diese Einschränkung gibt es bei ISO-C selbst m.W. nicht.
Doch. Die kommt eigentlich da her.
Rufus Τ. F. schrieb:> Im Draft für C-99 tauchen weder isodd noch iseven auf, und das sieht im> Draft für C-11 (N1570) nicht anders aus.
Das liegt daran, daß es nicht explizit um diese Identifier geht, sondern
um alle, die mit "is" gefolgt von einem Kleinbuchstaben anfangen. Diese
sind reserviert für zukünftige Erweiterungen der Standardbibliothek. Das
gilt übrigens nicht nur für Namen, die mit "is" anfangen, sondern auch
für "to" und "str".
Zu finden ist das in C99 im Kapitel 7.26 "Future library directions".
Rolf M. schrieb:> Zu finden ist das in C99 im Kapitel 7.26 "Future library directions".
(Um das zu finden, reicht die von mir verwandte simple Volltextsuche
natürlich nicht)
Danke!
Bastler schrieb:> Der Name tut nicht zur Sache, denn die Funktion hat ein anderes Problem:> sie funktioniert nicht!
Auf welche Funktion beziehst du dich?
Jan H. schrieb:> Mir liegt es näher, eine mathematische Eigenschaft mit einer> mathematischen Funktion zu prüfen, statt mit einer, die auf einem> Zahlensystem basiert. Ist aber persönliche Vorliebe.
Ja. Persönliche Vorlieben zählen gelegentlich mehr als der Rest der
Welt.
Der eigentliche Punkt ist jedoch ein wenig anders. Wir haben es hier
definitionsgemäß mit Integerzahlen zu tun, oder versuchst du gar, einer
Gleitkommazahl eine Eigenschaft Gerade/Ungerade zuzuordnen? 2.0000 ist
gerade, 1.99999999999987 ist dann was? oder 1.23456789E68 ? Und wo soll
die Grenze sein?
Also.
Wir haben Integerzahlen.
Basta.
Dort hat ein jedes Bit eine festgelegte Wertigkeit und eines dieser Bits
hat die Wertigkeit 2^0, also 1. Für die Eigenschaft Gerade oder Ungerade
ist das Prüfen genau dieses Bits das eigentliche Kriterium. Das Gerede
von "Prüfung mit mathematischen Funktionen" ist in diesem Lichte nur
Gebabbel.
W.S.
W.S. schrieb:> Dort hat ein jedes Bit eine festgelegte Wertigkeit und> eines dieser Bits hat die Wertigkeit 2^0, also 1. Für> die Eigenschaft Gerade oder Ungerade ist das Prüfen> genau dieses Bits das eigentliche Kriterium.
Ahh ja.
(-2 mod 2) ist in der üblichen Standard-Mathematik gleich
Null; mithin ist -2 gerade. Nachlesbar in jedem Mathe-Buch.
Bitte erläutere, wie das mit der Prüfung des LSB korrespondiert,
wenn auf der gewählten Plattform Integerzahlen in Einerkomplement-
darstellung (!!) codiert sind.
Vielen Dank im Voraus.
Bastler schrieb:> Wo ist also> die Prüfung auf 3, 5, 7 und 9? Nich sind 40% aller Ergebnisse falsch!
Das macht nichts. In 90% aller unit-Tests würde die Funktion bestehen.
Es würde getestet auf 0, 1, -1 und 32768.
Rolf M. schrieb:> Das liegt daran, daß es nicht explizit um diese Identifier geht, sondern> um alle, die mit "is" gefolgt von einem Kleinbuchstaben anfangen. Diese> sind reserviert für zukünftige Erweiterungen der Standardbibliothek. Das> gilt übrigens nicht nur für Namen, die mit "is" anfangen, sondern auch> für "to" und "str".> Zu finden ist das in C99 im Kapitel 7.26 "Future library directions".
Solche interessanten Schnipsel sind der Grund, warum ich auch
sinnlos-Diskussionen so gerne weiterverfolge. Ich hätte eine derartige
Funktion (von der Implementierung mal abgesehen) vermutlich tatsächlich
je nach Tageslaune "iseven" oder "isEven" genannt.
A. K. schrieb:> Dummerweise war in meinem Code aber weit und breit kein "if" zu sehen.
Dummerweise bist du nicht das Mass aller Dinge. Gefragt war nach dem
bool'schen Ergebnis ob eine Zahl gerade oder ungerade ist. Da ist eine
-1 oder 1 als Ergebnis in C vollkommen egal. Ausserdem weiss der
Compiler welche Zahl mod ist, nämlich 2, und kennt den Typ der
hingehenden Zahl, das könnte ja unsigned sein.
Wie man's dreht und wendet, alle sind klüger als du.
Viel besser ist aber die Umsetzung von
a in Z ist gerade <==> a in 2·Z <==> existiert k in Z so dass a = 2
* k.
Hier also die ultimative Lösung (C99):
1
#include<stdbool.h>
2
#include<limits.h>
3
4
booliseven(inta)
5
{
6
booleven=false;
7
intk=INT_MIN;
8
9
while(true)
10
{
11
// Avoid C's undefined behavior on signed overflow!
12
// Only perform 2 * k if it won't overflow.
13
if(k>=INT_MIN/2&&k<=INT_MAX/2)
14
if(a==2*k)
15
even=true;
16
if(k==INT_MAX)
17
break;
18
else
19
k++;
20
}
21
22
returneven;
23
}
...damit unsere Compiler-Optimatoren wie Michael ein bisschen was zu
kniffeln haben.
Wenn deine Optimierungen dann "a & 1" liefern, dann bist du *echt* gut!
Rolf M. schrieb:> Klaus schrieb:>> Einfach hinschreiben, was man wirklich meint, und dann>> klapts in jeder Sprache.>> Du schreibst in beiden Fällen nicht hin, was du meinst.
Doch.
Gerade Zahlen sind, wenn mich die Reste meiner Mathekenntnisse
nicht trügen, so definiert, dass sie bei Division durch 2 den
Rest Null lassen ( = sich ohne Rest teilen lassen).
In Zeichen: N mod 2 = 0.
Michael B. schrieb:> Gefragt war nach dem> bool'schen Ergebnis ob eine Zahl gerade oder ungerade ist. Da ist eine> -1 oder 1 als Ergebnis in C vollkommen egal.
Und genau dann erzeugt der Compiler aus (a % 2) != 0 oder if(a % 2)
optimalen Code. Warum hattest du dich dann über den Compiler so bitter
beschwert?
... schrieb:>> wenn auf der gewählten Plattform Integerzahlen in>> Einerkomplementdarstellung (!!) codiert sind.>> Einerkomplement ist heute praktisch irrelefant.
Dein Einwand ist irrelevant. Du hast das Problem nicht
verstanden.
"mod" basiert direkt auf der DEFINITION der geraden
Zahl und muss damit auf jeder Plattform und mit jeder
beliebigen internen Darstellung von Ganzzahlen korrekt
funktionieren.
Die Lösung mit "&" hängt von der internen Zahldarstellung
ab.
Possetitjel schrieb:> Die Lösung mit "&" hängt von der internen Zahldarstellung ab.
Und woher bitte hast du dieses "Wissen"?
§ 6.2.6 Representations of types
§ 6.2.6.1 General
.3 Values stored in unsigned bit-fields and objects of type unsigned
char shall be represented using a pure binary notation. *)
*) A positional representation for integers that uses the binary digits
0 and 1, in which the values represented by successive bits are
additive, begin with 1, and are multiplied by successive integral powers
of 2, except perhaps the bit with the highest position. (Adapted from
the American National Dictionary for Information Processing Systems.) A
byte contains CHAR_BIT bits, and the values of type unsigned char range
from 0 to 2^CHAR_BIT - 1.
§ 6.2.6.2 Integer types
.1 For unsigned integer types other than unsigned char, the bits of the
object representation shall be divided into two groups: value bits and
padding bits (there need not be any of the latter). If there are N value
bits, each bit shall represent a different power of 2 between 1 and
2^{N-1}, so that objects of that type shall be capable of representing
values from 0 to 2^N - 1 using a pure binary representation; this shall
be known as the value representation. The values of any padding bits are
unspecified.
Possetitjel schrieb:> Die Lösung mit "&" hängt von der internen Zahldarstellung> ab.
Bitte nenne uns eine Integer-Darstellung, bei der das geringstwertige
Bit NICHT die Wertigkeit 2^0 hat.
Und das möglichst ohne endloses Rumgelabere.
Georg
Johann L. schrieb:> Possetitjel schrieb:>> Die Lösung mit "&" hängt von der internen Zahldarstellung ab.>> Und woher bitte hast du dieses "Wissen"?>> § 6.2.6 Representations of types>> § 6.2.6.1 General>> .3 Values stored in unsigned bit-fields and objects of type unsigned> char shall be represented using a pure binary notation. […]>> § 6.2.6.2 Integer types>> .1 For unsigned integer types other than unsigned char, […]
Das n & 1 liefert zwar für nichtnegative Werte das gewünschte Ergebnis,
nicht aber für negative Werte in Einerkomplementdarstellung. n % 2 != 0
hingegen funktioniert immer.
Hier sind übrigens noch zwei weitere, funktional angehauchte Einzeiler
für odd und even (welches ich aus ästhetischen Gründen in evn umbenannt
habe):
1
boolodd(intn);
2
3
boolevn(intn){returnn==0||odd(n+(n<0)-(n>0));}
4
5
boolodd(intn){returnn!=0&&evn(n+(n<0)-(n>0));}
Auch diese Funktionen vermag der GCC nicht auf eine oder zwei Assembler-
Instruktionen zu reduzieren, aber immerhin löst er (mit -O2) die
Rekursion auf, so dass auch bei großen Argumenten kein Stack-Überlauf
entsteht.
Georg schrieb:> Possetitjel schrieb:>> Die Lösung mit "&" hängt von der internen Zahldarstellung>> ab.>> Bitte nenne uns eine Integer-Darstellung, bei der das> geringstwertige Bit NICHT die Wertigkeit 2^0 hat.>> Und das möglichst ohne endloses Rumgelabere.
Falls Du vorhast, es demnächst mal mit Höflichkeit zu
versuchen, können wir uns unterhalten.
Tschüss bis dahin.
Johann L. schrieb:>> Die Lösung mit "&" hängt von der internen Zahldarstellung ab.>> Und woher bitte hast du dieses "Wissen"?
Dass das immer funktioniert, ist gar nicht die Frage.
Der Unterschied besteht darin, ob man sich innerhalb der
Abstraktionsebene des eigentlichen Problems bewegt:
"Zahl ist gerade, wenn Zahl mod 2 gleich Null ist."
Oder ob man die Frage, die auf der "mathematischen" Ebene (ganze Zahlen)
angeordnet ist, beantwortet, indem man einen Umweg über die tiefere
Ebene der internen Zahldarstellung geht:
"Zahl ist gerade, wenn [hier gedanklich eine Ebene tiefer schalten
in den Bereich der Bits] die letzte Stelle der binären Darstellung
0 ist."
Ob man diesen Ebenunterschied überhaupt versteht/wahrnimmt, und, falls
ja, ob man das abstraktionsebenenübergreifende Programmieren als
unnötige Komplexität oder als natürlich empfindet, ist von Person zu
Person sehr verschieden.
Grüße aus dem Elfenbeinturm ;)
Tom schrieb:> Johann L. schrieb:>>> Die Lösung mit "&" hängt von der internen Zahldarstellung>>> ab.>>>> Und woher bitte hast du dieses "Wissen"?>> Dass das immer funktioniert, ist gar nicht die Frage.
Häh?
Sagt mal, Leute, LEST ihr manchmal auch, worum's geht?
Weiter oben ging es darum, dass man bei
--> NEGATIVEN <--
Zahlen, die in
--> EINERKOMPLEMENT-DARSTELLUNG <--
vorliegen, NICHT durch verUNDen bestimmen kann, ob die Zahl gerade
ist oder nicht. ES FUNKIONIERT NICHT! ES KOMMT DAS FALSCHE HERAUS!
"+2" sieht irgendwie so aus: "...000010"
"-2" sieht im Einerkomplement so aus: "...111101"
Klingelt's?
Ist das eventuell ein Grund (neben deutlich wichtigeren), warum 2-er
Komplement beliebter ist?
Der Elfenbeinturm ist scheinbar auch zum Schutz der Anderen da.
Nur mal eine Frage nebenbei: Wird die Einerkomplement-Darstellung
überhaupt irgendwo angewendet?
Eine Darstellung, die zwei Darstellungen der Zahl "0" hat (-0 und +0)
und wo bei Rechenoperationen, die über die 0-Grenze hinweggehen, das
Ergebnis falsch ist und nur durch anschließende Addition von 1
richtiggestellt wird.
Wird das irgendwo angewendet, oder ist das lediglich eine theoretische
Darstellungsmöglichkeit?
Possetitjel schrieb:> Weiter oben ging es darum, dass man bei>> --> NEGATIVEN <-->> Zahlen, die in>> --> EINERKOMPLEMENT-DARSTELLUNG <-->> vorliegen, NICHT durch verUNDen bestimmen kann, ob die Zahl gerade> ist oder nicht. ES FUNKIONIERT NICHT! ES KOMMT DAS FALSCHE HERAUS!unterschreib
Aber ist sinnlos, die raffens net mit ihrer Mikrooptimierung.
Premature optimization is the root of all evil.
Schreib das hin, was du meinst. Nicht das, von dem du glaubst, dass es
effizienter ist.
asd schrieb:> Wird das irgendwo angewendet, oder ist das lediglich eine theoretische> Darstellungsmöglichkeit?
UNIVAC... früher.
Aber solange das noch im Standard zulässig ist, kann man sich ja
aussuchen, ob man diese beknackte Mikrooptimierung mit "&" macht oder ob
man hinschreibt, was man tatsächlich meint.
Portabel ist halt nur letzeres.
Nase schrieb:> Portabel ist halt nur letzeres.
Sehe ich genauso.
Ich wollte es nur wissen, weil ich noch nie gesehen habe, daß die
Einerkomplementdarstellung irgendwo angewendet wurde.
Danke für die Auskunft!
Johann L. schrieb:> fast_int8_t_promoted_to_int_equals_fast_int8_t_promoted_to_int_divided_b
y_two_multiplied_by_two_as_fast_int8_t
Hmmm.... ohne auto-Vervollständigen dürfte der Name ziemlich
fehlerträchtig sein. Und wenn man alle Funktionen nach diesem Schema
benennt, sind mit den ersten 32 Zeichen
"fast_int8_t_promoted_to_int_equa" vermutlich viele Namenskonflikte zu
erwarten. Dein Vorschlag erscheint mir deshalb praxisfern.
Nase schrieb:> asd schrieb:>> Wird das irgendwo angewendet, oder ist das lediglich eine theoretische>> Darstellungsmöglichkeit?> UNIVAC... früher.
In den 60er Jahren gab es die Einerkomplementdarstellung noch in einigen
anderen Systeme, u.a. von CDC.
Aber auch heute gibt es sie noch, nämlich in den Servern ClearPath
Dorado 880/88E und 890/89E des Univac-Nachfolgers Unisys. Die Produktion
dieser Server soll aber Ende dieses Jahres eingestellt werden:
http://www.computerworld.com.au/article/547767/unisys_phasing_decades-old_mainframe_processor_x86_chips/
Die Datentypen dieser Rechner umfassen übrigens 9 Bit (char), 18 Bit
(short), 36 Bit (int und long) und 72 Bit (long long).
Ich schätze, dass Unisys einen Vertreter mit großer Klappe im ISO-C
Konsortium sitzen hat(te), der die Unterstützung dieser unüblichen
Datenformate durchsetzte, ähnlich wie IBM einen hinschickte, der den
Rausschmiss der Trigraphs aus dem C-Standard verhinderte.
> "mod" basiert direkt auf der DEFINITION der geraden> Zahl und muss damit auf jeder Plattform und mit jeder> beliebigen internen Darstellung von Ganzzahlen korrekt> funktionieren.
Da sch..ss ich doch drauf. Ich benutze schon lange keinen Abakus mehr.
Welch ein Drama! Große Teile der weltweiten C-Source-Bestände sind nicht
UNIVAC kompatibel. Daß es die heute noch gibt, liegt nur daran, daß
manche Firmen wohl noch COBOL-Programme haben, die sie nicht ersetzen
können/wollen.
Für alle die das nicht wissen: das waren die Maschinen aus den Doris Day
Filmen, die man vor 45 Jahren schon als alte Schinken Sonntags
nachmittags sehen konnte.
Wann kommt der AVR in der 9-Bit-UNIVAC-Edition?
Die Bedingung "mindestens 31 signifikante Zeichen" bedeutet aber nicht,
das mehr nicht sein darf. GCC hat keine Beschränkung. Eventuell aber die
BinUtils der entsprechenden Ziel-Hardware, denn daraus benutzt GCC
zumindest den Linker.
Was von Namen unbegrenzter (2GB) Länge zu halten ist: je länger desto
unlesbarer. Nur wenn man C++-Namensräume/Klassen per
Names-Konkatenierung implementieren will, dann bekommt man solche eben.
Bastler schrieb:> Die Bedingung "mindestens 31 signifikante Zeichen" bedeutet aber nicht,> das mehr nicht sein darf.
Aber sie bedeutet, daß mehr nicht portabel ist, und da hier ja so großer
Wert auf Portabilität gelegt wird, verbieten sich damit mehr als 31
Zeichen für den Namen.
Portabilität kann auch bedeuten: auf allen Plattformen, die GCc
unterstützt. Ich käme eh aus anderen Gründen nicht auf die Idee, so
lange Namen zu verwenden,
Und zur ursprünglichen Fragestellung: Ist es ein echtes Problem, wenn
ich die "isOddOrNot"-Routine im Fall der Fälle auf "UNIVAC" anpassen
muß. Ich würd's überleben, genau wie 99,999% aller
"Nicht-Museums-Programmierer".
Jan H. schrieb:> 4 mod 2 = 0>> Doch, also das ist ziemlich einfach zum schreiben und (für mich)> verständlicher als obige Bitmanipulation.
Modulo ist aber relativ aufwändig zu rechnen, falls der von dir
verwendete C-Compiler nicht auf den Spezialfall "Modulo 2" optimiert
ist. Und du hattest nach der schnellsten Möglichkeit gefragt.
Oder meintest du damit, wo du am wenigsten nachdenken musst und das
Programm deshalb schnell geschrieben ist?
richard schrieb:> was ist wohl in C die einfachste bzw. schnellste Möglichkeit,
Hallo,
Bastler schrieb:> Da kann man schön sehen, was passiert wenn OO doch "auch mit> prozeduralen Sprachen geht".
Was nichts an der schlichten Tatsache ändert, daß es geht und
offensichtlich auch in der Praxis benutzt wird.
Liebe Grüße,
Karl
Echt?
Ich glaube es geht sogar ohne Hochsprache. Wie sollte die Maschine das
auch anstellen, die kann nur Maschinenbefehle. Für sie, die Maschine,
wurde Hochsprachen aber auch nicht erfunden, sondern um konkrete
Probleme zu lösen. Und in 39-stellige Namen verschlüsselte 3..4
Namespaces sind eher der Weisheit letzter Stuss.
Hui, das sind ja immerhin 49 Zeichen!
Und da es auch noch den Identifier
1
gtk_radio_menu_item_new_with_mnemonic
gibt, der mit dem obigen die ersten 37 Zeichen gemeinsam hat, können die
GTK-Entwickler ja froh sein, dass sich der GCC diesbezüglich nicht auf
die Mindestanforderung des C-Standards (31 Zeichen) beschränkt :)
Mann oh Mann, heute wird aber wieder mal kein cm Boden an den Feind
verschenkt. Die Frage war nach der 1. Antwort geklärt. Was ist denn los?
Die Hitze ist doch abgeklungen.
Bastler schrieb:> Ja, aber die 1. Antwort war eben nicht auf UNIVAC portiebar. Das Problem> ist schon gravierend ;-)
Tut mir leid, das hatte ich übersehen. Attacke...
Hallo,
Bastler schrieb:> Echt?> Ich glaube es geht sogar ohne Hochsprache. Wie sollte die Maschine das> auch anstellen, die kann nur Maschinenbefehle. Für sie, die Maschine,> wurde Hochsprachen aber auch nicht erfunden, sondern um konkrete> Probleme zu lösen. Und in 39-stellige Namen verschlüsselte 3..4> Namespaces sind eher der Weisheit letzter Stuss.
Da hast Du natürlich Recht. Der Weisheit allerletzter Stuss wäre es
aber, bescheuerte Namensgebung als Argument gegen Sprachen,
Sprachfamilien oder Paradigmen anführen zu wollen. Sowas liegt am
Programmierer. ;-)
Liebe Grüße,
Karl
Karl Käfer schrieb:> Bastler schrieb:>> Da kann man schön sehen, was passiert wenn OO doch "auch mit>> prozeduralen Sprachen geht".>> Was nichts an der schlichten Tatsache ändert, daß es geht und> offensichtlich auch in der Praxis benutzt wird.
Ich würde das eher umgekehrt formulieren. Es geht zwar und wird auch in
der Praxis benutzt, ist aber trotzdem Mist. ;-)