diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index c3fe1de15db955da4ce45fd6de88ede86c053b83..8a28312b348a507835ff4361024e4ca3ce7c28ad 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -174,3 +174,12 @@ SELECT GREATEST(d,d) FROM t1 WHERE k=2;
 GREATEST(d,d)
 NULL
 DROP TABLE t1;
+select 1197.90 mod 50;
+1197.90 mod 50
+47.90
+select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
+5.1 mod 3	5.1 mod -3	-5.1 mod 3	-5.1 mod -3
+2.1	2.1	-2.1	-2.1
+select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
+5 mod 3	5 mod -3	-5 mod 3	-5 mod -3
+2	2	-2	-2
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index e7bcd81a15edc8f216a9e65bfe49e8f2eafc1e68..eb506a588708fbd07e2d0255c32a479431144655 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -94,3 +94,16 @@ CREATE TABLE t1 (d varchar(6), k int);
 INSERT INTO t1 VALUES (NULL, 2);
 SELECT GREATEST(d,d) FROM t1 WHERE k=2;
 DROP TABLE t1;
+
+#
+# Bug #6138: mod and doubles
+#
+
+select 1197.90 mod 50;
+select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
+
+#
+# Test for mod and signed integers
+#
+
+select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index f20d69bf2ad3a091632914f985341ef833b34f55..17cf8642ce52f1242dccb6069fb3484cf8a55aee 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -651,11 +651,11 @@ void Item_func_int_div::fix_length_and_dec()
 double Item_func_mod::val()
 {
   DBUG_ASSERT(fixed == 1);
-  double value= floor(args[0]->val()+0.5);
-  double val2=floor(args[1]->val()+0.5);
-  if ((null_value=val2 == 0.0 || args[0]->null_value || args[1]->null_value))
+  double x= args[0]->val();
+  double y= args[1]->val();
+  if ((null_value= (y == 0.0) || args[0]->null_value || args[1]->null_value))
     return 0.0; /* purecov: inspected */
-  return fmod(value,val2);
+  return fmod(x, y);
 }
 
 longlong Item_func_mod::val_int()
@@ -670,10 +670,7 @@ longlong Item_func_mod::val_int()
 
 void Item_func_mod::fix_length_and_dec()
 {
-  max_length=args[1]->max_length;
-  decimals=0;
-  maybe_null=1;
-  find_num_type();
+  Item_num_op::fix_length_and_dec();
 }