2009-11-14 3 views
5

MySQL (5.0.45)는 부호없는 수학을 사용하여 이상한 내부 형 변환을 수행합니까? 나는 부호없는 정수를 저장하고 있지만 기본적인 산술을 선택할 때 나는 터무니없는 숫자를 얻을 :MySQL 정수 부호없는 산술 문제가 있습니까?

mysql> create table tt (a integer unsigned , b integer unsigned , c float); 
Query OK, 0 rows affected (0.41 sec) 

mysql> insert into tt values (215731,216774,1.58085); 
Query OK, 1 row affected (0.00 sec) 

mysql> select a,b,c from tt; 
+--------+--------+---------+ 
| a  | b  | c  | 
+--------+--------+---------+ 
| 215731 | 216774 | 1.58085 | 
+--------+--------+---------+ 
1 row in set (0.02 sec) 

mysql> select (a-b)/c from tt; 
+---------------------+ 
| (a-b)/c    | 
+---------------------+ 
| 1.1668876878652e+19 | 
+---------------------+ 
1 row in set (0.00 sec) 

mysql> -- WHAT? 
mysql> select a-b from tt; 
+----------------------+ 
| a-b     | 
+----------------------+ 
| 18446744073709550573 | 
+----------------------+ 
1 row in set (0.02 sec) 

나는 이것이 빼기가 부정적이며 따라서 부호로 결과를지도하려고 노력하고 넘쳐된다는 사실과 관련이있다 가정 ? 서명 된 모든 것을 변경하여이 문제를 해결할 수 있지만 32 비트 정수를 사용하여 좀 더 긍정적 인 공간을 갖는 것을 선호합니다.

나는 MySQL에서 이것을 실행하지 않았고, 나는 서명되지 않은 MySQL 산술 연산을 많이했다. 이것이 일반적인 문제입니까?

+0

중복 : http://stackoverflow.com/questions/1517556/mysql-query-gone-wild –

답변

7

빼기 연산자의 왼쪽 또는 오른쪽이 부호가없는 경우 결과에도 부호가 없습니다. the NO_UNSIGNED_SUBTRACTION SQL mode을 설정하여이를 변경할 수 있습니다.

또는 서명되지 않은 값을 부호있는 bigint 값으로 명시 적으로 캐스팅 한 다음 빼기를 수행 할 수도 있습니다.

+0

새로운 문서가 링크 : HTTP : // dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_unsigned_subtraction ............................. .................................................. ........................ MariaDB : https://mariadb.com/kb/en/mariadb/sql_mode/ –

2

그래, 중간 빼기는 64 비트 랩 어라운드를 수행했습니다. 32 비트 정수를 예상했지만 실제로 64를 얻으므로 부호없는 (unsigned) 부호를 사용할 이유가 없습니다.

+0

분명히 내 메모리 그래프를 상상해보십시오. 우리는 1 인당 1 조 9,000 억 yob에서 메모리 할당을 유지할 수있었습니다. 둘째. 바로 스타 트렉 컴퓨팅입니다. – Xailor

3

이 시도 :

mysql> select cast(cast(a-b as unsigned) as signed)/c from tt; 

+-----------------------------------------+ 
| cast(cast(a-b as unsigned) as signed)/c | 
+-----------------------------------------+ 
|      -659.771639688953 | 
+-----------------------------------------+ 
1 row in set (0.00 sec) 

참조 : http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html