Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch num_work Excluding Merge-Ins
This is equivalent to a diff from 9afc42d70d to 3cac6cdb86
2013-02-14
| ||
15:32 | Fold in Peter Reid's fixes and enhancements to the sqlite4_num object. check-in: 8ede88c1df user: drh tags: trunk | |
01:51 | Fix sqlite4_num_to_text when formatting an integer with a negative exponent. It was leaving an uninitialized byte in the destination string. Leaf check-in: 3cac6cdb86 user: peterreid tags: num_work | |
2013-02-11
| ||
14:03 | Add test fixture functions for sqlite4_num_isinf and sqlite4_num_isnan, and some related test cases. check-in: 58a9cfcb39 user: peterreid tags: num_work | |
2013-02-09
| ||
16:55 | Have worker clients and writers that discard an old in-memory tree update a read-lock slot before concluding their work or write transaction. This is required for read-only clients - which cannot set the value of their own read-lock slot. check-in: 798d9e23be user: dan tags: trunk | |
05:27 | Make LARGEST_UINT64 unsigned. This was causing adjustExponent to fail when compiled with msvc. check-in: 9ff6991d9f user: peterreid tags: num_work | |
2013-02-08
| ||
15:22 | Avoid extending the database file when truncating it to the minimum number of blocks required during system shutdown. check-in: 9afc42d70d user: dan tags: trunk | |
14:39 | Changes to lsm_unix.c to build on android: (a) do not use fdatasync() on android and (b) account for the fact that usleep() returns void on android. check-in: 302b222395 user: dan tags: trunk | |
Changes to src/math.c.
︙ | ︙ | |||
211 212 213 214 215 216 217 218 219 220 221 222 223 224 | r.sign = A.sign ^ B.sign; r.approx = A.approx | B.approx; if( r.approx==0 && A.m%B.m!=0 ) r.approx = 1; r.m = A.m/B.m; r.e = A.e - B.e; return r; } /* ** Compare numbers A and B. Return: ** ** 1 if A<B ** 2 if A==B ** 3 if A>B | > > > > > > > > > > > > > > | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | r.sign = A.sign ^ B.sign; r.approx = A.approx | B.approx; if( r.approx==0 && A.m%B.m!=0 ) r.approx = 1; r.m = A.m/B.m; r.e = A.e - B.e; return r; } /* ** Test if A is infinite. */ int sqlite4_num_isinf(sqlite4_num A){ return A.e>SQLITE4_MX_EXP && A.m!=0; } /* ** Test if A is NaN. */ int sqlite4_num_isnan(sqlite4_num A){ return A.e>SQLITE4_MX_EXP && A.m==0; } /* ** Compare numbers A and B. Return: ** ** 1 if A<B ** 2 if A==B ** 3 if A>B |
︙ | ︙ | |||
237 238 239 240 241 242 243 244 245 246 247 248 249 250 | return A.sign ? 1 : 3; } if( B.e>SQLITE4_MX_EXP ){ if( B.m==0 ) return 0; return B.sign ? 3 : 1; } if( A.sign!=B.sign ){ return A.sign ? 1 : 3; } adjustExponent(&A, &B); if( A.sign ){ sqlite4_num t = A; A = B; B = t; | > | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | return A.sign ? 1 : 3; } if( B.e>SQLITE4_MX_EXP ){ if( B.m==0 ) return 0; return B.sign ? 3 : 1; } if( A.sign!=B.sign ){ if ( A.m==0 && B.m==0 ) return 2; return A.sign ? 1 : 3; } adjustExponent(&A, &B); if( A.sign ){ sqlite4_num t = A; A = B; B = t; |
︙ | ︙ | |||
319 320 321 322 323 324 325 | i = incr; }else if( zIn[0]=='+' ){ i = incr; }else{ i = 0; } if( nIn<=0 ) goto not_a_valid_number; | | | < < < < | | | | | | | | | | | | | | | | | | | | | > | | > > > > > > > > > > > > > > > > > > > > | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | i = incr; }else if( zIn[0]=='+' ){ i = incr; }else{ i = 0; } if( nIn<=0 ) goto not_a_valid_number; if( nIn>=incr*3 && ((c=zIn[i])=='i' || c=='I') && ((c=zIn[i+incr])=='n' || c=='N') && ((c=zIn[i+incr*2])=='f' || c=='F') ){ r.e = SQLITE4_MX_EXP+1; r.m = nIn<=i+incr*3 || zIn[i+incr*3]==0; return r; } while( i<nIn && (c = zIn[i])!=0 ){ i += incr; if( c>='0' && c<='9' ){ if( c=='0' && nDigit==0 ){ if( seenRadix && r.e > -(SQLITE4_MX_EXP+1000) ) r.e--; continue; } nDigit++; if( nDigit<=18 ){ r.m = (r.m*10) + c - '0'; if( seenRadix ) r.e--; }else{ if( c!='0' ) r.approx = 1; if( !seenRadix ) r.e++; } }else if( c=='.' ){ seenRadix = 1; }else if( c=='e' || c=='E' ){ int exp = 0; int expsign = 0; int nEDigit = 0; if( zIn[i]=='-' ){ expsign = 1; i += incr; }else if( zIn[i]=='+' ){ i += incr; } if( i>=nIn ) goto not_a_valid_number; while( i<nIn && (c = zIn[i])!=0 ){ i += incr; if( c<'0' || c>'9' ) goto not_a_valid_number; if( c=='0' && nEDigit==0 ) continue; nEDigit++; if( nEDigit>3 ) goto not_a_valid_number; exp = exp*10 + c - '0'; } if( expsign ) exp = -exp; r.e += exp; break; }else{ goto not_a_valid_number; } } return r; not_a_valid_number: r.e = SQLITE4_MX_EXP+1; r.m = 0; return r; } /* ** Convert an sqlite4_int64 to a number and return that number. */ sqlite4_num sqlite4_num_from_int64(sqlite4_int64 n){ sqlite4_num r; r.approx = 0; r.e = 0; r.sign = n < 0; if( n>=0 ){ r.m = n; }else if( n!=SMALLEST_INT64 ){ r.m = -n; }else{ r.m = 1+(u64)LARGEST_INT64; } return r; } /* ** Convert an integer into text in the buffer supplied. The ** text is zero-terminated and right-justified in the buffer. ** A pointer to the first character of text is returned. ** ** The buffer needs to be at least 21 bytes in length. |
︙ | ︙ | |||
465 466 467 468 469 470 471 | zNum += m; n -= m; removeTrailingZeros(zNum, &n); if( n>0 ){ zOut[0] = '.'; memcpy(zOut+1, zNum, n); nOut += n; | < | > > > | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | zNum += m; n -= m; removeTrailingZeros(zNum, &n); if( n>0 ){ zOut[0] = '.'; memcpy(zOut+1, zNum, n); nOut += n; zOut[n+1] = 0; }else{ zOut[0] = 0; } return nOut; } if( x.e<0 && x.e >= -n-5 ){ /* Values less than 1 and with no more than 5 subsequent zeros prior ** to the first significant digit. Ex: 0.0000012345 */ int j = -(n + x.e); memcpy(zOut, "0.", 2); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
4343 4344 4345 4346 4347 4348 4349 | ** Every number in SQLite is represented in memory by an instance of ** the following object. */ typedef struct sqlite4_num sqlite4_num; struct sqlite4_num { unsigned char sign; /* Sign of the overall value */ unsigned char approx; /* True if the value is approximate */ | | | 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 | ** Every number in SQLite is represented in memory by an instance of ** the following object. */ typedef struct sqlite4_num sqlite4_num; struct sqlite4_num { unsigned char sign; /* Sign of the overall value */ unsigned char approx; /* True if the value is approximate */ short e; /* The exponent. */ sqlite4_uint64 m; /* The significant */ }; /* ** CAPI4REF: Operations On SQLite Number Objects */ sqlite4_num sqlite4_num_add(sqlite4_num, sqlite4_num); |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
460 461 462 463 464 465 466 | /* ** Constants for the largest and smallest possible 64-bit signed integers. ** These macros are designed to work correctly on both 32-bit and 64-bit ** compilers. */ #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | /* ** Constants for the largest and smallest possible 64-bit signed integers. ** These macros are designed to work correctly on both 32-bit and 64-bit ** compilers. */ #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. */ #define ROUND8(x) (((x)+7)&~7) |
︙ | ︙ |
Added test/num.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the sqlite_*_printf() interface. # # $Id: printf.test,v 1.31 2009/02/01 00:21:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test num-1.1.1 { sqlite4_num_compare 20 20 } {equal} do_test num-1.1.2 { sqlite4_num_compare 20 2e1 } {equal} do_test num-1.1.3 { sqlite4_num_compare -00034 -3.4e1 } {equal} do_test num-1.1.4 { sqlite4_num_compare -inf +inf } {lesser} do_test num-1.1.5 { sqlite4_num_compare -inf 0 } {lesser} do_test num-1.1.6 { sqlite4_num_compare inf 4 } {greater} do_test num-1.1.7 { sqlite4_num_compare nan 7 } {incomparable} # Is +0 > -0? #do_test num-equal-1.1.4 { # sqlite4_num_compare +0 -0 #} {equal} do_test num-2.1.1 { sqlite4_num_to_text [sqlite4_num_from_text 37] } {37} do_test num-2.1.2 { sqlite4_num_to_text [sqlite4_num_from_text 37 2] } {37} do_test num-2.1.4 { sqlite4_num_compare [sqlite4_num_from_text 2.9e2X 5] 290 } {equal} do_test num-2.1.5 { sqlite4_num_isnan [sqlite4_num_from_text inf 2] } {true} do_test num-2.1.6 { sqlite4_num_isinf [sqlite4_num_from_text inf 3] } {true} do_test num-3.1.1 { sqlite4_num_to_text [sqlite4_num_add 5 7] } {12} do_test num-4.1.1 { sqlite4_num_to_text [sqlite4_num_sub 9 3] } {6} do_test num-4.1.2 { sqlite4_num_to_text [sqlite4_num_sub 5 12] } {-7} do_test num-4.2.1 { sqlite4_num_compare [sqlite4_num_sub 1 1] [sqlite4_num_sub -1 -1] } {equal} do_test num-5.1.1 { sqlite4_num_to_text [sqlite4_num_mul 9 8] } {72} do_test num-6.1.1 { sqlite4_num_to_text [sqlite4_num_div 6 5] } {1.2} do_test num-6.1.2 { sqlite4_num_compare 2 [sqlite4_num_div 2 1] } {equal} do_test num-6.1.3 { sqlite4_num_to_text [sqlite4_num_div 2 1] } {2} do_test num-6.1.4 { sqlite4_num_to_text [sqlite4_num_div 22 10] } {2.2} finish_test |
Changes to test/test_main.c.
︙ | ︙ | |||
4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 | Tcl_AppendResult(interp, " ", aOpt[i].zOptName); } return TCL_ERROR; } sqlite4_test_control(SQLITE4_TESTCTRL_OPTIMIZATIONS, db, mask); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite4_search_count; extern int sqlite4_found_count; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 | Tcl_AppendResult(interp, " ", aOpt[i].zOptName); } return TCL_ERROR; } sqlite4_test_control(SQLITE4_TESTCTRL_OPTIMIZATIONS, db, mask); return TCL_OK; } #define NUM_FORMAT "sign:%d approx:%d e:%d m:%lld" /* Append a return value representing a sqlite4_num. */ static void append_num_result( Tcl_Interp *interp, sqlite4_num A ){ char buf[100]; sprintf( buf, NUM_FORMAT, A.sign, A.approx, A.e, A.m ); Tcl_AppendResult(interp, buf, 0); } /* Convert a string either representing a sqlite4_num (listing its fields as ** returned by append_num_result) or that can be parsed as one. Invalid ** strings become NaN. */ static sqlite4_num test_parse_num( char *arg ){ sqlite4_num A; int sign, approx, e; if( sscanf( arg, NUM_FORMAT, &sign, &approx, &e, &A.m)==4 ){ A.sign = sign; A.approx = approx; A.e = e; return A; } else { return sqlite4_num_from_text(arg, -1, 0); } } /* Convert return values of sqlite4_num to strings that will be readable in ** the tests. */ static char *describe_num_comparison( int code ){ switch( code ){ case 0: return "incomparable"; case 1: return "lesser"; case 2: return "equal"; case 3: return "greater"; default: return "error"; } } /* Compare two numbers A and B. Returns "incomparable", "lesser", "equal", ** "greater", or "error". */ static int test_num_compare( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite4_num A, B; int cmp; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " NUM NUM\"", 0); return TCL_ERROR; } A = test_parse_num( argv[1] ); B = test_parse_num( argv[2] ); cmp = sqlite4_num_compare(A, B); Tcl_AppendResult( interp, describe_num_comparison( cmp ), 0); return TCL_OK; } /* Create a sqlite4_num from a string. The optional second argument specifies ** how many bytes may be read. */ static int test_num_from_text( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite4_num A; int len; if( argc!=2 && argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " STRING\" or \"", argv[0], " STRING INTEGER\"", 0); return TCL_ERROR; } if( argc==3 ){ if ( Tcl_GetInt(interp, argv[2], &len) ) return TCL_ERROR; }else{ len = -1; } A = sqlite4_num_from_text( argv[1], len, 0 ); append_num_result(interp, A); return TCL_OK; } static int test_num_to_text( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ char text[30]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " NUM\"", 0); return TCL_ERROR; } sqlite4_num_to_text( test_parse_num( argv[1] ), text ); Tcl_AppendResult( interp, text, 0 ); return TCL_OK; } static int test_num_binary_op( Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv, /* Text of each argument */ sqlite4_num (*op) (sqlite4_num, sqlite4_num) ){ sqlite4_num A, B, R; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " NUM NUM\"", 0); return TCL_ERROR; } A = test_parse_num(argv[1]); B = test_parse_num(argv[2]); R = op(A, B); append_num_result(interp, R); return TCL_OK; } static int test_num_add( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ return test_num_binary_op( interp, argc, argv, sqlite4_num_add ); } static int test_num_sub( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ return test_num_binary_op( interp, argc, argv, sqlite4_num_sub ); } static int test_num_mul( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ return test_num_binary_op( interp, argc, argv, sqlite4_num_mul ); } static int test_num_div( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ return test_num_binary_op( interp, argc, argv, sqlite4_num_div ); } static int test_num_predicate( Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv, /* Text of each argument */ int (*pred) (sqlite4_num) ){ sqlite4_num A; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " NUM\"", 0); return TCL_ERROR; } A = test_parse_num(argv[1]); Tcl_AppendResult(interp, pred(A) ? "true" : "false", 0); return TCL_OK; } static int test_num_isinf( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ return test_num_predicate( interp, argc, argv, sqlite4_num_isinf ); } static int test_num_isnan( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ return test_num_predicate( interp, argc, argv, sqlite4_num_isnan ); } /* ** Register commands with the TCL interpreter. */ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite4_search_count; extern int sqlite4_found_count; |
︙ | ︙ | |||
4398 4399 4400 4401 4402 4403 4404 | { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, { "sqlite4_interrupt", (Tcl_CmdProc*)test_interrupt }, { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, { "sqlite4_get_autocommit", (Tcl_CmdProc*)get_autocommit }, { "sqlite4_stack_used", (Tcl_CmdProc*)test_stack_used }, { "printf", (Tcl_CmdProc*)test_printf }, | | > > > > > > > > > | 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 | { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, { "sqlite4_interrupt", (Tcl_CmdProc*)test_interrupt }, { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, { "sqlite4_get_autocommit", (Tcl_CmdProc*)get_autocommit }, { "sqlite4_stack_used", (Tcl_CmdProc*)test_stack_used }, { "printf", (Tcl_CmdProc*)test_printf }, { "sqlite4IoTrace", (Tcl_CmdProc*)test_io_trace }, { "sqlite4_num_compare", (Tcl_CmdProc*)test_num_compare }, { "sqlite4_num_from_text", (Tcl_CmdProc*)test_num_from_text }, { "sqlite4_num_to_text", (Tcl_CmdProc*)test_num_to_text }, { "sqlite4_num_add", (Tcl_CmdProc*)test_num_add }, { "sqlite4_num_sub", (Tcl_CmdProc*)test_num_sub }, { "sqlite4_num_mul", (Tcl_CmdProc*)test_num_mul }, { "sqlite4_num_div", (Tcl_CmdProc*)test_num_div }, { "sqlite4_num_isinf", (Tcl_CmdProc*)test_num_isinf }, { "sqlite4_num_isnan", (Tcl_CmdProc*)test_num_isnan }, }; static struct { char *zName; Tcl_ObjCmdProc *xProc; void *clientData; } aObjCmd[] = { { "sqlite4_connection_pointer", get_sqlite_pointer, 0 }, |
︙ | ︙ |