On 2015-11-27 17:41, Stefan Ram <
r...@zedat.fu-berlin.de> wrote:
> In C kann man (ich weiß aber nicht, ob das voll portabel ist)
> eine Bereichsprüfung auf [0, $tage] (ich zeige es mit $tage = 3)
> mit nur einem Vergleich erledigen:
>
> #include <stdio.h>
>
> static inline range( unsigned int i )
> { printf( "%2d, %s\n",( int )i, i < 3 ? "in range" : "" ); }
>
> int main( void )
> { for( int i = -2; i < 5; ++ i )range( i ); }
>
> -2,
> -1,
> 0, in range
> 1, in range
> 2, in range
> 3,
> 4,
>
> In MySQL gibt es zwar auch INTEGER UNSIGNED, aber ausgerechnet
> das bei den Typen und Prüfungen sonst so laxe MySQL erlaubt dort
> solche Bitreinterpretationen nicht.
In C ist ein Cast von signed int auf unsigned int keine
Bitreinterpretation, sondern eine mathematisch definierte Operation
(modulo UINT_MAX+1), die unabhängig von der Zahlenrepräsentation auf
Bitebene ist (in der üblichen Zweierkomplement-Darstellung ist die
Repräsentation allerdings tatsächlich gleich).
MySQL verwendet ebenfalls eine definierte Operation, aber eine andere:
Bei der Zuweisung an einen Integer-Typ werden Werte die zu klein sind
auf das Minimum, solche, die zu groß sind, auf das Maximum gesetzt:
mysql> desc foo;
+-------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| i | int(11) | YES | | NULL | |
| u | int(10) unsigned | YES | | NULL | |
| si | smallint(6) | YES | | NULL | |
| su | smallint(5) unsigned | YES | | NULL | |
+-------+----------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
...
mysql> update foo set u=i, su=i, si=i;
Query OK, 1 row affected, 13 warnings (0.00 sec)
Rows matched: 9 Changed: 1 Warnings: 13
mysql> select * from foo order by i;
+--------+-------+--------+-------+
| i | u | si | su |
+--------+-------+--------+-------+
| -70000 | 0 | -32768 | 0 |
| -40000 | 0 | -32768 | 0 |
| -30000 | 0 | -30000 | 0 |
| -1 | 0 | -1 | 0 |
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 30000 | 30000 | 30000 | 30000 |
| 40000 | 40000 | 32767 | 40000 |
| 70000 | 70000 | 32767 | 65535 |
+--------+-------+--------+-------+
9 rows in set (0.00 sec)
Ach ja, man beachte "Warnings: 13":
mysql> show warnings ;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'u' at row 1 |
| Warning | 1264 | Out of range value for column 'su' at row 1 |
| Warning | 1264 | Out of range value for column 'si' at row 4 |
| Warning | 1264 | Out of range value for column 'su' at row 5 |
| Warning | 1264 | Out of range value for column 'si' at row 5 |
| Warning | 1264 | Out of range value for column 'u' at row 6 |
| Warning | 1264 | Out of range value for column 'su' at row 6 |
| Warning | 1264 | Out of range value for column 'si' at row 6 |
| Warning | 1264 | Out of range value for column 'u' at row 7 |
| Warning | 1264 | Out of range value for column 'su' at row 7 |
| Warning | 1264 | Out of range value for column 'si' at row 7 |
| Warning | 1264 | Out of range value for column 'u' at row 8 |
| Warning | 1264 | Out of range value for column 'su' at row 8 |
+---------+------+---------------------------------------------+
13 rows in set (0.00 sec)