mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix for bug #26788 "mysqld (debug) aborts when inserting specific
numbers into char fields" and bug #12860 "Difference in zero padding of exponent between Unix and Windows" Rewrote the code that determines what 'precision' argument should be passed to sprintf() to fit the string representation of the input number into the field. We get finer control over conversion by pre-calculating the exponent, so we are able to determine which conversion format, 'e' or 'f', will be used by sprintf(). We also remove the leading zero from the exponent on Windows to make it compatible with the sprintf() output on other platforms. mysql-test/r/insert.result: Added test cases for bug #26788 and bug #31152. mysql-test/t/cast.test: Removed --replace_result, since the result is now correct on Windows. mysql-test/t/insert.test: Added test cases for bug #26788 and bug #31152. mysql-test/t/type_float.test: Removed --replace_result, since the result is now correct on Windows. mysql-test/t/variables.test: Removed --replace_result, since the result is now correct on Windows. sql/field.cc: Rewrote the code that determines what 'precision' argument should be passed to sprintf() to fit the string representation of the input number into the field. We get finer control over conversion by pre-calculating the exponent, so we are able to determine which conversion format, 'e' or 'f', will be used by sprintf().
This commit is contained in:
@ -461,4 +461,124 @@ i
|
|||||||
2
|
2
|
||||||
2
|
2
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a char(20) NOT NULL,
|
||||||
|
b char(7) DEFAULT NULL,
|
||||||
|
c char(4) DEFAULT NULL
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (9.999999e+0, 9.999999e+0, 9.999e+0);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e-05, 1.225e-05, 1.225e-05);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'c' at row 1
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-04, 1.225e-04);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-01, 1.225e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225877e-01, 1.225877e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e+01, 1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+05, 1.225e+05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+10, 1.225e+10);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+15, 1.225e+15);
|
||||||
|
INSERT INTO t1(a,b) VALUES (5000000e+0, 5000000e+0);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+78, 1.25e+78);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-94, 1.25e-94);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+203, 1.25e+203);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-175, 1.25e-175);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.225e+0, 1.225e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.37e+0, 1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.37e+0, -1.37e+0);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'c' at row 1
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.87e-3, 1.87e-3);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'c' at row 1
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.87e-2, -1.87e-2);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'c' at row 1
|
||||||
|
INSERT INTO t1(a,c) VALUES (5000e+0, 5000e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-5000e+0, -5000e+0);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'c' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
9.999999000000000748 10 10
|
||||||
|
1.225e-05 1.2e-05 1e-0
|
||||||
|
0.0001225 0.00012 NULL
|
||||||
|
0.122499999999999998 0.1225 NULL
|
||||||
|
0.122587699999999994 0.12259 NULL
|
||||||
|
12.25 12.25 NULL
|
||||||
|
12.25 12.25 12.2
|
||||||
|
122500 122500 NULL
|
||||||
|
12250000000 1.2e+10 NULL
|
||||||
|
1225000000000000 1.2e+15 NULL
|
||||||
|
5000000 5000000 NULL
|
||||||
|
1.25e+78 1.2e+78 NULL
|
||||||
|
1.25e-94 1.2e-94 NULL
|
||||||
|
1.25e+203 1e+203 NULL
|
||||||
|
1.25e-175 1e-175 NULL
|
||||||
|
1.225000000000000089 NULL 1.23
|
||||||
|
1.370000000000000107 NULL 1.37
|
||||||
|
-1.37 NULL -1.3
|
||||||
|
0.00187 NULL 0.00
|
||||||
|
-0.0187 NULL -0.0
|
||||||
|
5000 NULL 5000
|
||||||
|
-5000 NULL -500
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a char(20) NOT NULL,
|
||||||
|
b char(7) DEFAULT NULL,
|
||||||
|
c char(5)
|
||||||
|
);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (9.999999e+0, 9.999999e+0, 9.999e+0);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e-05, 1.225e-05, 1.225e-05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-04, 1.225e-04);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-01, 1.225e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225877e-01, 1.225877e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e+01, 1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+05, 1.225e+05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+10, 1.225e+10);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+15, 1.225e+15);
|
||||||
|
INSERT INTO t1(a,b) VALUES (5000000e+0, 5000000e+0);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+78, 1.25e+78);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-94, 1.25e-94);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+203, 1.25e+203);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-175, 1.25e-175);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.225e+0, 1.225e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.37e+0, 1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.37e+0, -1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.87e-3, 1.87e-3);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.87e-2, -1.87e-2);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'c' at row 1
|
||||||
|
INSERT INTO t1(a,c) VALUES (5000e+0, 5000e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-5000e+0, -5000e+0);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
9.999999000000000748 10 9.999
|
||||||
|
1.225e-05 1.2e-05 1e-05
|
||||||
|
0.0001225 0.00012 NULL
|
||||||
|
0.122499999999999998 0.1225 NULL
|
||||||
|
0.122587699999999994 0.12259 NULL
|
||||||
|
12.25 12.25 NULL
|
||||||
|
12.25 12.25 12.25
|
||||||
|
122500 122500 NULL
|
||||||
|
12250000000 1.2e+10 NULL
|
||||||
|
1225000000000000 1.2e+15 NULL
|
||||||
|
5000000 5000000 NULL
|
||||||
|
1.25e+78 1.2e+78 NULL
|
||||||
|
1.25e-94 1.2e-94 NULL
|
||||||
|
1.25e+203 1e+203 NULL
|
||||||
|
1.25e-175 1e-175 NULL
|
||||||
|
1.225000000000000089 NULL 1.225
|
||||||
|
1.370000000000000107 NULL 1.37
|
||||||
|
-1.37 NULL -1.37
|
||||||
|
0.00187 NULL 0.002
|
||||||
|
-0.0187 NULL -0.01
|
||||||
|
5000 NULL 5000
|
||||||
|
-5000 NULL -5000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t (a CHAR(10),b INT);
|
||||||
|
INSERT INTO t VALUES (),(),();
|
||||||
|
INSERT INTO t(a) SELECT rand() FROM t;
|
||||||
|
DROP TABLE t;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -177,8 +177,6 @@ select cast(1.0e+300 as signed int);
|
|||||||
CREATE TABLE t1 (f1 double);
|
CREATE TABLE t1 (f1 double);
|
||||||
INSERT INTO t1 SET f1 = -1.0e+30 ;
|
INSERT INTO t1 SET f1 = -1.0e+30 ;
|
||||||
INSERT INTO t1 SET f1 = +1.0e+30 ;
|
INSERT INTO t1 SET f1 = +1.0e+30 ;
|
||||||
# Expected result is +-1e+30, but Windows returns +-1e+030.
|
|
||||||
--replace_result 1e+030 1e+30
|
|
||||||
SELECT f1 AS double_val, CAST(f1 AS SIGNED INT) AS cast_val FROM t1;
|
SELECT f1 AS double_val, CAST(f1 AS SIGNED INT) AS cast_val FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
@ -353,5 +353,86 @@ SELECT * FROM t2;
|
|||||||
|
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #26788: mysqld (debug) aborts when inserting specific numbers into char
|
||||||
|
# fields
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a char(20) NOT NULL,
|
||||||
|
b char(7) DEFAULT NULL,
|
||||||
|
c char(4) DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (9.999999e+0, 9.999999e+0, 9.999e+0);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e-05, 1.225e-05, 1.225e-05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-04, 1.225e-04);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-01, 1.225e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225877e-01, 1.225877e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e+01, 1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+05, 1.225e+05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+10, 1.225e+10);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+15, 1.225e+15);
|
||||||
|
INSERT INTO t1(a,b) VALUES (5000000e+0, 5000000e+0);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+78, 1.25e+78);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-94, 1.25e-94);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+203, 1.25e+203);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-175, 1.25e-175);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.225e+0, 1.225e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.37e+0, 1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.37e+0, -1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.87e-3, 1.87e-3);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.87e-2, -1.87e-2);
|
||||||
|
INSERT INTO t1(a,c) VALUES (5000e+0, 5000e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-5000e+0, -5000e+0);
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
a char(20) NOT NULL,
|
||||||
|
b char(7) DEFAULT NULL,
|
||||||
|
c char(5)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (9.999999e+0, 9.999999e+0, 9.999e+0);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e-05, 1.225e-05, 1.225e-05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-04, 1.225e-04);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e-01, 1.225e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225877e-01, 1.225877e-01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b,c) VALUES (1.225e+01, 1.225e+01, 1.225e+01);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+05, 1.225e+05);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+10, 1.225e+10);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.225e+15, 1.225e+15);
|
||||||
|
INSERT INTO t1(a,b) VALUES (5000000e+0, 5000000e+0);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+78, 1.25e+78);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-94, 1.25e-94);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e+203, 1.25e+203);
|
||||||
|
INSERT INTO t1(a,b) VALUES (1.25e-175, 1.25e-175);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.225e+0, 1.225e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.37e+0, 1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.37e+0, -1.37e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (1.87e-3, 1.87e-3);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-1.87e-2, -1.87e-2);
|
||||||
|
INSERT INTO t1(a,c) VALUES (5000e+0, 5000e+0);
|
||||||
|
INSERT INTO t1(a,c) VALUES (-5000e+0, -5000e+0);
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #31152: assertion in Field_str::store(double)
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t (a CHAR(10),b INT);
|
||||||
|
INSERT INTO t VALUES (),(),();
|
||||||
|
INSERT INTO t(a) SELECT rand() FROM t;
|
||||||
|
DROP TABLE t;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
@ -116,15 +116,10 @@ drop table if exists t1;
|
|||||||
# Check conversion of floats to character field (Bug #7774)
|
# Check conversion of floats to character field (Bug #7774)
|
||||||
create table t1 (c char(20));
|
create table t1 (c char(20));
|
||||||
insert into t1 values (5e-28);
|
insert into t1 values (5e-28);
|
||||||
# Expected result is "5e-28", but windows returns "5e-028"
|
|
||||||
--replace_result 5e-028 5e-28
|
|
||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (c char(6));
|
create table t1 (c char(6));
|
||||||
insert into t1 values (2e5),(2e6),(2e-4),(2e-5);
|
insert into t1 values (2e5),(2e6),(2e-4),(2e-5);
|
||||||
# Expected result is "2e+06", but windows returns "2e+006"
|
|
||||||
# Expected result is "2e-05", but windows returns "2e-005"
|
|
||||||
--replace_result 2e+006 2e+06 2e-005 2e-05
|
|
||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
|||||||
set @select=2,@t5=1.23456;
|
set @select=2,@t5=1.23456;
|
||||||
select @`select`,@not_used;
|
select @`select`,@not_used;
|
||||||
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
|
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
|
||||||
# Expected result "1e-10", windows returns "1e-010"
|
|
||||||
--replace_result 1e-010 1e-10
|
|
||||||
select @test_int,@test_double,@test_string,@test_string2,@select;
|
select @test_int,@test_double,@test_string,@test_string2,@select;
|
||||||
set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
|
set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
|
||||||
select @test_int,@test_double,@test_string,@test_string2;
|
select @test_int,@test_double,@test_string,@test_string2;
|
||||||
|
74
sql/field.cc
74
sql/field.cc
@ -5907,24 +5907,70 @@ int Field_str::store(double nr)
|
|||||||
{
|
{
|
||||||
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
|
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
|
||||||
uint length;
|
uint length;
|
||||||
bool use_scientific_notation= TRUE;
|
|
||||||
uint local_char_length= field_length / charset()->mbmaxlen;
|
uint local_char_length= field_length / charset()->mbmaxlen;
|
||||||
/*
|
|
||||||
Check fabs(nr) against longest value that can be stored in field,
|
|
||||||
which depends on whether the value is < 1 or not, and negative or not
|
|
||||||
*/
|
|
||||||
double anr= fabs(nr);
|
double anr= fabs(nr);
|
||||||
int neg= (nr < 0.0) ? 1 : 0;
|
int neg= (nr < 0.0) ? 1 : 0;
|
||||||
if (local_char_length > 4 && local_char_length < 32 &&
|
uint max_length;
|
||||||
(anr < 1.0 ? anr > 1/(log_10[max(0,(int) local_char_length-neg-2)]) /* -2 for "0." */
|
int exp;
|
||||||
: anr < log_10[local_char_length-neg]-1))
|
uint digits;
|
||||||
use_scientific_notation= FALSE;
|
uint i;
|
||||||
|
|
||||||
length= (uint) my_sprintf(buff, (buff, "%-.*g",
|
/* Calculate the exponent from the 'e'-format conversion */
|
||||||
(use_scientific_notation ?
|
if (anr < 1.0 && anr > 0)
|
||||||
max(0, (int)local_char_length-neg-5) :
|
{
|
||||||
local_char_length),
|
for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100);
|
||||||
nr));
|
for (; anr < 1e-10; exp-= 10, anr*= 1e10);
|
||||||
|
for (i= 1; anr < 1 / log_10[i]; exp--, i++);
|
||||||
|
exp--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100);
|
||||||
|
for (; anr > 1e10; exp+= 10, anr/= 1e10);
|
||||||
|
for (i= 1; anr > log_10[i]; exp++, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
max_length= local_char_length - neg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Since in sprintf("%g") precision means the number of significant digits,
|
||||||
|
calculate the maximum number of significant digits if the 'f'-format
|
||||||
|
would be used (+1 for decimal point if the number has a fractional part).
|
||||||
|
*/
|
||||||
|
digits= max(0, (int) max_length - (nr != trunc(nr)));
|
||||||
|
/*
|
||||||
|
If the exponent is negative, decrease digits by the number of leading zeros
|
||||||
|
after the decimal point that do not count as significant digits.
|
||||||
|
*/
|
||||||
|
if (exp < 0)
|
||||||
|
digits= max(0, (int) digits + exp);
|
||||||
|
/*
|
||||||
|
'e'-format is used only if the exponent is less than -4 or greater than or
|
||||||
|
equal to the precision. In this case we need to adjust the number of
|
||||||
|
significant digits to take "e+NN" + decimal point into account (hence -5).
|
||||||
|
We also have to reserve one additional character if abs(exp) >= 100.
|
||||||
|
*/
|
||||||
|
if (exp >= (int) digits || exp < -4)
|
||||||
|
digits= max(0, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
|
||||||
|
|
||||||
|
length= (uint) my_sprintf(buff, (buff, "%-.*g", digits, nr));
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
/*
|
||||||
|
Windows always zero-pads the exponent to 3 digits, we want to remove the
|
||||||
|
leading 0 to match the sprintf() output on other platforms.
|
||||||
|
*/
|
||||||
|
if ((exp >= (int) digits || exp < -4) && exp > -100 && exp < 100)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(length >= 6); /* 1e+NNN */
|
||||||
|
uint tmp= length - 3;
|
||||||
|
buff[tmp]= buff[tmp + 1];
|
||||||
|
tmp++;
|
||||||
|
buff[tmp]= buff[tmp + 1];
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
+1 below is because "precision" in %g above means the
|
+1 below is because "precision" in %g above means the
|
||||||
max. number of significant digits, not the output width.
|
max. number of significant digits, not the output width.
|
||||||
|
Reference in New Issue
Block a user