SQLite

Check-in [d6b1df1a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improvements to the layout and comments for the new round() implementation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | round-up-2
Files: files | file ages | folders
SHA3-256: d6b1df1a224e06b1fae3c217c334bc0480fa4d824e4a84d6ea690159382d6e18
User & Date: drh 2024-06-12 10:17:36
Context
2024-06-12
10:17
Improvements to the layout and comments for the new round() implementation. (Leaf check-in: d6b1df1a user: drh tags: round-up-2)
00:30
Test cases for the round() function for values within one epsilon of the 5 round-up threshold. (check-in: 552b1b10 user: drh tags: round-up-2)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

453
454
455
456
457
458
459







460
461
462
463
464
465
466
467
468
469
470
471








472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
  }else{
    sqlite3_int64 ii = (sqlite3_int64)(x+0.5);
    return (double)ii;
  }
}
#endif








/*
** Implementation of the round() function
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int n = 0;        /* Second argument. Digits to the right of decimal point */
  double r;         /* First argument.  Value to be rounded */
  double rX = 1.0;  /* Scaling factor.  pow(10,n) */
  double rSgn;      /* Sign of the first first */
  static const double rTwoPowerMinus52 =  /* pow(2,-52) */
                           2.220446049250313080847263336181640625e-16;
  assert( argc==1 || argc==2 );








  if( argc==2 ){
    double rY = 10;
    int i;
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
    n = sqlite3_value_int(argv[1]);
    if( n>30 ) n = 30;
    if( n<0 ) n = 0;
    for(i=n, rY=10; i>0; i>>=1, rY=rY*rY){
      if( i&1 ) rX *= rY;
    }
  }
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  r = sqlite3_value_double(argv[0]);
  if( r<0 ){
    rSgn = -1.0;
    r = -r;
  }else{
    rSgn = 1.0;
  }
  r = rSgn*sqlite3Round(r*rX + rX*r*rTwoPowerMinus52)/rX;
  sqlite3_result_double(context, r);
}
#endif

/*
** Allocate nByte bytes of space using sqlite3Malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify







>
>
>
>
>
>
>








|
<
<

>
>
>
>
>
>
>
>

|
|








<
<
<
<
<
<
<
<
|







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475


476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495








496
497
498
499
500
501
502
503
  }else{
    sqlite3_int64 ii = (sqlite3_int64)(x+0.5);
    return (double)ii;
  }
}
#endif

/*
** This is the value of the least significant bit of the significand
** relative to the total magnitude of the number for an IEEE754 binary64.
** Since the significant is 53 bits, this is pow(2,-52).
*/
#define SQLITE_DOUBLE_EPSILON 2.220446049250313080847263336181640625e-16

/*
** Implementation of the round() function
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int n = 0;        /* Second argument. Digits to the right of decimal point */
  double r;         /* First argument.  Value to be rounded */
  double rX = 1.0;  /* Scaling factor.  pow(10,n) */
  double rSgn;      /* Sign of the first argument */


  assert( argc==1 || argc==2 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  r = sqlite3_value_double(argv[0]);
  if( r<0 ){
    rSgn = -1.0;
    r = -r;
  }else{
    rSgn = 1.0;
  }
  if( argc==2 ){
    double rY = 10.0;   /* Use to compute rX */
    int i;              /* Loop counter for computing rX */
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
    n = sqlite3_value_int(argv[1]);
    if( n>30 ) n = 30;
    if( n<0 ) n = 0;
    for(i=n, rY=10; i>0; i>>=1, rY=rY*rY){
      if( i&1 ) rX *= rY;
    }
  }








  r = rSgn*sqlite3Round(r*rX + rX*r*SQLITE_DOUBLE_EPSILON)/rX;
  sqlite3_result_double(context, r);
}
#endif

/*
** Allocate nByte bytes of space using sqlite3Malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify