Explizite Datentyp-Umwandlungen
Obwohl die Gleitkommazahl "1.0" und die ganze Zahl "1" für Menschen als gleich erscheinen könnten (immerhin sind es beide die gleiche Zahl „Eins“), sind es in formalen Sprachen doch meistens zwei verschiedene Werte aus zwei verschiedenen Datentypen.
Die ganze Zahl "1" und die Gleitkommazahl "1.0" haben auch unterschiedliche Darstellungen als Bittupel. In der folgenden Abbildung wird zunächst das Bittupel der Gleitkommazahl "1.0" dargestellt und anschließend das Bittupel der ganzen Zahl "1". Diese Bittupel können sich von System zu System unterscheiden und die folgende Abbildung gibt daher nur ein Beispiel wieder.
Darstellungen der 1
0011111111110000000000000000000000000000000000000000000000000000
00000000000000000000000000000001
Die meisten formalen Sprachen erlauben es aber, in einigen Fällen einen Wert eines Datentyps in den „entsprechenden“ Wert eines anderen Datentyps umzuwandeln. (Nicht immer ist es offensichtlich, welcher Wert das sein sollte.)
Praktisch immer besteht die Möglichkeit einer Umwandlung zwischen ganzen Zahlen und Gleitkommazahlen. Bei solchen Umwandlungen können aber Informationen, wie etwa Nachkommastellen, verloren gehen, so daß sich nach einer Rückwandlung in eine Gleitkommazahl nicht wieder die ursprüngliche Zahl ergeben muß.
So wird die Gleitkommazahl "1.4" in die ganze Zahl "1" umgewandelt. Auch eine zu große Gleitkommazahl kann nicht immer so in eine Ganzzahl gewandelt werden, daß bei einer Rückwandlung wieder der ursprüngliche Wert entsteht.
In einigen Fällen werden Typwandlungen von formalen Sprachen implizit angenommen, also ohne daß die Wandlung im Quelltext ausdrücklich verlangt wird.
Es gibt aber auch oft Schreibweisen (Operatoren, Aufrufe oder Sonderschreibweisen), um eine Typwandlung im Quelltext ausdrücklich zu verlangen. Solche ausdrücklichen Typwandlungen sollten selten nötig sein und möglichst vermieden werden, weil sie den Sinn von Datentypen, Werte verschiedener Typen nicht durcheinanderzubringen, leicht sabotieren können. Dennoch gibt es bestimmte Situationen, in denen eine explizite Typwandlung gebraucht wird.
Eine Typwandlung kann man als eine Abbildung verstehen, die Werten eines bestimmten Datentyps Werte eines anderen Datentyps zuordnet. Eine solche Typwandlung wird manchmal durch etwas Aufrufbares und manchmal durch Operatoren bereitgestellt.
Anhang
Wortkunde “cast ”
In einigen Programmiersprachen wird eine Schreibweise zur Typwandlung als “cast (operator) ” bezeichnet. Das englische Verb “to cast ” (USA-Aussprache [kæst]) bedeutet hier soviel wie “(um)formen”. Es kommt über das Mittelenglische “casten ” vom altnordischen „kasta“ (werfen?), das wohl um 1000-1400 ins Englische übernommen wurde (oder entstand?). Das Altnordische (Old Norse, ON ) wurde vor und um 1000 AD in Skandinavien gesprochen (bis in das 6. Jahrhundert: „Urnordisch“, bis ins 8. Jahrhundert: „Späturnordisch“). Es wird heute nicht mehr verwendet, aber es ist die älteste germanische Sprache oder eine der ältesten germanischen Sprachen, von der Schriften überliefert sind. „kasta “ ist verwandt mit „kos “ („Haufen“, “heap ”) und vielleicht verwandt mit dem lateinischen „gerere “. Das Wort wird allgemein verwendet für einen Wurf, das was geworfen wurde (oder wird) oder das, in das etwas geworfen wird. Aus dem letzten Sinn leitet sich die Verwendung zur Bezeichnung einer Form und des Vorganges des (Um-)formens ab, wie sie in den formalen Sprachen verwendet wird.
C -Programm zur Bittupel-Darstellung
Das folgende C -Programm wurde verwendet, um die obenstehenden Bittupel der Gleitkommazahl 1 und der ganzen Zahl 1 auszugeben. Zum Verständnis des Programms ausreichende C -Kenntnisse sollen hier nicht als bekannt vorausgesetzt werden. Das folgende Programm kann daher bei der Lektüre dieser Lektion ignoriert werden, es erscheint nur als Ergänzung dieser Lektion für daran interessierte Leser.
bitprint.c
#include <stdio.h> /* putchar */
#include <limits.h> /* CHAR_BIT */
#define DUMP(T,w) { const T const v = w; \
dump( &v, sizeof( v )); putchar( '\n' ); }
static void dump( const void * const buffer, int j )
{ const char * const b = buffer; while( j-- )
{ for( int i = CHAR_BIT; i--; )
putchar( '1' - !( b[ j ]& 1 << i )); }}
int main( void ){ DUMP(double,1.0) DUMP(int,1) }stdout
0011111111110000000000000000000000000000000000000000000000000000
00000000000000000000000000000001stdout
0000000000000000000000000000000000000000000000001111000000111111
00000001000000000000000000000000