Add the "!" flag to the "%g" mprintf conversion parameter to force a

decimal point.  This prevents floating point values from appearing as
integers.  Use this flag when converting floating point to text.
Ticket #1362. (CVS 2586)

FossilOrigin-Name: 4b98dace6b90abf4a6fe1cd51e6392fd213358c4
This commit is contained in:
drh 2005-08-13 12:59:14 +00:00
parent 592ac8cb6c
commit 557cc60f4d
7 changed files with 121 additions and 73 deletions

View File

@ -1,5 +1,5 @@
C Make\sthe\sround()\sfunction\swork\scorrectly\son\snumbers\swith\svery\slarge\sexponents.\nTicket\s#1340.\s(CVS\s2585)
D 2005-08-13T03:07:47
C Add\sthe\s"!"\sflag\sto\sthe\s"%g"\smprintf\sconversion\sparameter\sto\sforce\sa\ndecimal\spoint.\s\sThis\sprevents\sfloating\spoint\svalues\sfrom\sappearing\sas\nintegers.\s\sUse\sthis\sflag\swhen\sconverting\sfloating\spoint\sto\stext.\nTicket\s#1362.\s(CVS\s2586)
D 2005-08-13T12:59:15
F Makefile.in 22ea9c0fe748f591712d8fe3c6d972c6c173a165
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -60,7 +60,7 @@ F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4
F src/parse.y d57cdd2adc0923762b40314f08683c836a2e0c90
F src/pragma.c 59ab7073465a11a531af2796e0385727194accb8
F src/prepare.c fa0f6068d9b8ec6d5c419c65d4d8ff747d49c5c6
F src/printf.c a06d3527c677334a97eaaa1573d0c644c987acf6
F src/printf.c d1fa64c696bc05f50471a960bc68cd9b6e861823
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
F src/select.c c611471052773b94af771693686bd5bcdbbb0dba
F src/shell.c 86c16f0d534aa51cc82cf9f66903d4eb681580e7
@ -85,7 +85,7 @@ F src/vdbeInt.h 9be9a6c43d38124bd03cc5cf05715605b1789fd9
F src/vdbeapi.c dc5b78cabf8d6e33318bd3d4ed25307d2aadce9a
F src/vdbeaux.c d53139d819b887dac608ac4ae9a501baee3cd311
F src/vdbefifo.c b8805850afe13b43f1de78d58088cb5d66f88e1e
F src/vdbemem.c da8e8d6f29dd1323f782f000d7cd120027c9ff03
F src/vdbemem.c 89154caae3b8d4d0397e1235390fc4ff8aba4233
F src/where.c ac754c021f716e17337f45ffdc2436c6d5109fd3
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
@ -169,7 +169,7 @@ F test/malloc2.test 655b972372d2754a3f6c6ed54d7cfd18fde9bd32
F test/memdb.test 1860e060be810bf0775bc57408a5b7c4954bcaea
F test/memleak.test df2b2b96e77f8ba159a332299535b1e5f18e49ac
F test/minmax.test 9429a06f1f93acf76fcacafd17160a4392e88526
F test/misc1.test a4fe87c71f756ee36b08a698da46ea9c3b2471e7
F test/misc1.test be8aa484569fb82766ce14961ba377aed92f3d8b
F test/misc2.test 5c699af2fede2694736a9f45aea7e2f052686e15
F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03
F test/misc4.test edd3e3adf5b6e3b995b29843565ca58dd602f9a7
@ -182,7 +182,7 @@ F test/pager2.test 49c0f57c7da0b060f0486b85fdd074025caa694e
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
F test/pagesize.test cbc6a312b6f6c0f02619b189985df2a14164b690
F test/pragma.test 95ea907adf68459e1be6f310c9ae94d1d59c465b
F test/printf.test 96ae2891aa9e9ad3eba0bd7608ffe536437dd045
F test/printf.test dc39f7c66db3adfe754b4fc0b97fdd97fa06a9c8
F test/progress.test 16496001da445e6534afb94562c286708316d82f x
F test/quick.test a94d12658a2b590c1a5be580bef09bbb04c1266b
F test/quote.test 6d75cf635d93ba2484dc9cb378d88cbae9dc2c62
@ -198,7 +198,7 @@ F test/select4.test c239f516aa31f42f2ef7c6d7cd01105f08f934ca
F test/select5.test 2d414f712bff8e590091e08f9b7287600731be00
F test/select6.test 6559d16ad16edb7d6864f7e74a3d204d0af72486
F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6
F test/sort.test 8aaec2e01bf97691c96fd2f0294e635540bebcda
F test/sort.test 131787aadaa0eca8bc97eaf244bbde2380a4bb77
F test/subquery.test 0df3de0dbb65165b96ebe895550f1549d5439856
F test/subselect.test 3f3f7a940dc3195c3139f4d530385cb54665d614
F test/table.test d0e05ede3f6e5a8b79f8661ddcc4618cf7e69f8a
@ -291,7 +291,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
P 25cfe9390dda79bb2a7740b3d7380f517a4e8d1b
R c6274d9ed3a9c273a8983dbfcf799ac8
P 4f47c3c884e38b810450b6127ab33c7b86e6743c
R b3c296ac5d6a7b19a3b058edd9a64bc2
U drh
Z 745b1dec57cb9cc3d543dad039e1c761
Z faea32e5bc1b77c04bb69a0132002ae9

View File

@ -1 +1 @@
4f47c3c884e38b810450b6127ab33c7b86e6743c
4b98dace6b90abf4a6fe1cd51e6392fd213358c4

View File

@ -111,6 +111,7 @@ static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
{ 'd', 10, 1, etRADIX, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 6, etDYNSTRING, 0, 0 },
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
@ -122,7 +123,6 @@ static const et_info fmtinfo[] = {
{ 'f', 0, 1, etFLOAT, 0, 0 },
{ 'e', 0, 1, etEXP, 30, 0 },
{ 'E', 0, 1, etEXP, 14, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'G', 0, 1, etGENERIC, 14, 0 },
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
@ -210,6 +210,7 @@ static int vxprintf(
etByte flag_plussign; /* True if "+" flag is present */
etByte flag_blanksign; /* True if " " flag is present */
etByte flag_alternateform; /* True if "#" flag is present */
etByte flag_altform2; /* True if "$" flag is present */
etByte flag_zeropad; /* True if field width constant starts with zero */
etByte flag_long; /* True if "l" flag is present */
etByte flag_longlong; /* True if the "ll" flag is present */
@ -225,7 +226,7 @@ static int vxprintf(
" ";
#define etSPACESIZE (sizeof(spaces)-1)
#ifndef etNOFLOATINGPOINT
int exp; /* exponent of real numbers */
int exp, e2; /* exponent of real numbers */
double rounder; /* Used for rounding floating point values */
etByte flag_dp; /* True if decimal point should be shown */
etByte flag_rtz; /* True if trailing zeros should be removed */
@ -254,13 +255,14 @@ static int vxprintf(
}
/* Find out what flags are present */
flag_leftjustify = flag_plussign = flag_blanksign =
flag_alternateform = flag_zeropad = 0;
flag_alternateform = flag_altform2 = flag_zeropad = 0;
do{
switch( c ){
case '-': flag_leftjustify = 1; c = 0; break;
case '+': flag_plussign = 1; c = 0; break;
case ' ': flag_blanksign = 1; c = 0; break;
case '#': flag_alternateform = 1; c = 0; break;
case '!': flag_altform2 = 1; c = 0; break;
case '0': flag_zeropad = 1; c = 0; break;
default: break;
}
@ -436,9 +438,9 @@ static int vxprintf(
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( realvalue>0.0 ){
while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
while( realvalue>1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
while( realvalue>1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
while( realvalue>10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
if( exp>350 || exp<-350 ){
@ -468,51 +470,72 @@ static int vxprintf(
}else{
flag_rtz = 0;
}
/*
** The "exp+precision" test causes output to be of type etEXP if
** the precision is too large to fit in buf[].
/* If exp+precision causes the output to be too big for etFLOAT, then
** do etEXP instead
*/
if( xtype==etFLOAT && exp+precision>=etBUFSIZE-30 ){
xtype = etEXP;
}
if( xtype==etEXP ){
e2 = 0;
}else{
e2 = exp;
}
nsd = 0;
if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
flag_dp = (precision>0 || flag_alternateform);
if( prefix ) *(bufpt++) = prefix; /* Sign */
if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
for(exp++; exp<0 && precision>0; precision--, exp++){
*(bufpt++) = '0';
}
while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
*(bufpt--) = 0; /* Null terminate */
if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */
while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
}
bufpt++; /* point to next free slot */
}else{ /* etEXP or etGENERIC */
flag_dp = (precision>0 || flag_alternateform);
if( prefix ) *(bufpt++) = prefix; /* Sign */
*(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */
if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
bufpt--; /* point to last digit */
if( flag_rtz && flag_dp ){ /* Remove tail zeros */
while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
}
bufpt++; /* point to next free slot */
if( exp || flag_exp ){
*(bufpt++) = aDigits[infop->charset];
if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
else { *(bufpt++) = '+'; }
if( exp>=100 ){
*(bufpt++) = (exp/100)+'0'; /* 100's digit */
exp %= 100;
}
*(bufpt++) = exp/10+'0'; /* 10's digit */
*(bufpt++) = exp%10+'0'; /* 1's digit */
flag_dp = (precision>0) | flag_alternateform | flag_altform2;
/* The sign in front of the number */
if( prefix ){
*(bufpt++) = prefix;
}
/* Digits prior to the decimal point */
if( e2<0 ){
*(bufpt++) = '0';
}else{
for(; e2>=0; e2--){
*(bufpt++) = et_getdigit(&realvalue,&nsd);
}
}
/* The decimal point */
if( flag_dp ){
*(bufpt++) = '.';
}
/* "0" digits after the decimal point but before the first
** significant digit of the number */
for(e2++; e2<0 && precision>0; precision--, e2++){
*(bufpt++) = '0';
}
/* Significant digits after the decimal point */
while( (precision--)>0 ){
*(bufpt++) = et_getdigit(&realvalue,&nsd);
}
/* Remove trailing zeros and the "." if no digits follow the "." */
if( flag_rtz && flag_dp ){
while( bufpt>buf && bufpt[-1]=='0' ) *(--bufpt) = 0;
if( bufpt>buf && bufpt[-1]=='.' ){
if( flag_altform2 ){
*(bufpt++) = '0';
}else{
*(--bufpt) = 0;
}
}
}
/* Add the "eNNN" suffix */
if( flag_exp || (xtype==etEXP && exp) ){
*(bufpt++) = aDigits[infop->charset];
if( exp<0 ){
*(bufpt++) = '-'; exp = -exp;
}else{
*(bufpt++) = '+';
}
if( exp>=100 ){
*(bufpt++) = (exp/100)+'0'; /* 100's digit */
exp %= 100;
}
*(bufpt++) = exp/10+'0'; /* 10's digit */
*(bufpt++) = exp%10+'0'; /* 1's digit */
}
*bufpt = 0;
/* The converted number is in buf[] and zero terminated. Output it.
** Note that the number is in the usual order, not reversed as with
** integer conversions. */

View File

@ -174,7 +174,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
*/
if( fg & MEM_Real ){
sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
}else{
assert( fg & MEM_Int );
sqlite3_snprintf(NBFS, z, "%lld", pMem->i);

View File

@ -13,7 +13,7 @@
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.35 2005/07/16 13:33:21 drh Exp $
# $Id: misc1.test,v 1.36 2005/08/13 12:59:16 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -316,13 +316,13 @@ do_test misc1-10.7 {
} {0 {}}
do_test misc1-10.8 {
execsql {SELECT x1 FROM manycol WHERE x0=100}
} {102}
} {102.0}
do_test misc1-10.9 {
catchsql "UPDATE manycol SET x1=x1+1 $::where AND rowid>0"
} {0 {}}
do_test misc1-10.10 {
execsql {SELECT x1 FROM manycol WHERE x0=100}
} {103}
} {103.0}
# Make sure the initialization works even if a database is opened while
# another process has the database locked.
@ -562,7 +562,7 @@ do_test misc1-17.1 {
COMMIT;
SELECT TestString FROM RealTable ORDER BY 1;
}
} {2 3}
} {2.0 3.0}
}
finish_test

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the sqlite_*_printf() interface.
#
# $Id: printf.test,v 1.15 2005/08/13 03:07:47 drh Exp $
# $Id: printf.test,v 1.16 2005/08/13 12:59:16 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -180,5 +180,30 @@ do_test printf-10.3 {
sqlite3_mprintf_double {%d %d %f} 1 1 1e300
} {1 1 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000}
# The non-standard '!' flag on a 'g' conversion forces a decimal point
# and at least one digit on either side of the decimal point.
#
do_test printf-11.1 {
sqlite3_mprintf_double {%d %d %!g} 1 1 1
} {1 1 1.0}
do_test printf-11.2 {
sqlite3_mprintf_double {%d %d %!g} 1 1 123
} {1 1 123.0}
do_test printf-11.3 {
sqlite3_mprintf_double {%d %d %!g} 1 1 12.3
} {1 1 12.3}
do_test printf-11.4 {
sqlite3_mprintf_double {%d %d %!g} 1 1 0.123
} {1 1 0.123}
do_test printf-11.5 {
sqlite3_mprintf_double {%d %d %!.15g} 1 1 1
} {1 1 1.0}
do_test printf-11.6 {
sqlite3_mprintf_double {%d %d %!.15g} 1 1 1e10
} {1 1 10000000000.0}
do_test printf-11.7 {
sqlite3_mprintf_double {%d %d %!.15g} 1 1 1e300
} {1 1 1.0e+300}
finish_test

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: sort.test,v 1.20 2005/07/21 03:15:01 drh Exp $
# $Id: sort.test,v 1.21 2005/08/13 12:59:16 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -106,27 +106,27 @@ do_test sort-2.1.1 {
UPDATE t1 SET v='x-2b' where v=='x-0.123';
SELECT v FROM t1 ORDER BY v;
}
} {x-123 x-2.15 x-2b x-3.141592653 x-4221 x0.0013442 x1.6 x11}
} {x-123.0 x-2.15 x-2b x-3.141592653 x-4221.0 x0.0013442 x1.6 x11}
do_test sort-2.1.2 {
execsql {
SELECT v FROM t1 ORDER BY substr(v,2,999);
}
} {x-123 x-2.15 x-2b x-3.141592653 x-4221 x0.0013442 x1.6 x11}
} {x-123.0 x-2.15 x-2b x-3.141592653 x-4221.0 x0.0013442 x1.6 x11}
do_test sort-2.1.3 {
execsql {
SELECT v FROM t1 ORDER BY substr(v,2,999)+0.0;
}
} {x-4221 x-123 x-3.141592653 x-2.15 x-2b x0.0013442 x1.6 x11}
} {x-4221.0 x-123.0 x-3.141592653 x-2.15 x-2b x0.0013442 x1.6 x11}
do_test sort-2.1.4 {
execsql {
SELECT v FROM t1 ORDER BY substr(v,2,999) DESC;
}
} {x11 x1.6 x0.0013442 x-4221 x-3.141592653 x-2b x-2.15 x-123}
} {x11 x1.6 x0.0013442 x-4221.0 x-3.141592653 x-2b x-2.15 x-123.0}
do_test sort-2.1.5 {
execsql {
SELECT v FROM t1 ORDER BY substr(v,2,999)+0.0 DESC;
}
} {x11 x1.6 x0.0013442 x-2b x-2.15 x-3.141592653 x-123 x-4221}
} {x11 x1.6 x0.0013442 x-2b x-2.15 x-3.141592653 x-123.0 x-4221.0}
# This is a bug fix for 2.2.4.
# Strings are normally mapped to upper-case for a caseless comparison.
@ -196,17 +196,17 @@ do_test sort-4.6 {
execsql {
SELECT v FROM t1 ORDER BY 1;
}
} {x-123 x-2.15 x-2b x-3.141592653 x-4.0e9 x-4221 x0.0013442 x01234567890123456789 x1.6 x11 x2.7 x5.0e10}
} {x-123.0 x-2.15 x-2b x-3.141592653 x-4.0e9 x-4221.0 x0.0013442 x01234567890123456789 x1.6 x11 x2.7 x5.0e10}
do_test sort-4.7 {
execsql {
SELECT v FROM t1 ORDER BY 1 DESC;
}
} {x5.0e10 x2.7 x11 x1.6 x01234567890123456789 x0.0013442 x-4221 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123}
} {x5.0e10 x2.7 x11 x1.6 x01234567890123456789 x0.0013442 x-4221.0 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123.0}
do_test sort-4.8 {
execsql {
SELECT substr(v,2,99) FROM t1 ORDER BY 1;
}
} {-123 -2.15 -2b -3.141592653 -4.0e9 -4221 0.0013442 01234567890123456789 1.6 11 2.7 5.0e10}
} {-123.0 -2.15 -2b -3.141592653 -4.0e9 -4221.0 0.0013442 01234567890123456789 1.6 11 2.7 5.0e10}
#do_test sort-4.9 {
# execsql {
# SELECT substr(v,2,99)+0.0 FROM t1 ORDER BY 1;