Changeset 11345


Ignore:
Timestamp:
Oct 21, 2010, 11:47:23 PM (11 years ago)
Author:
charles
Message:

(trunk libT) #3521 "rounding issue in tr_truncd()" -- try yet again to work out all the fringe cases :)

Location:
trunk/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/utils-test.c

    r11332 r11345  
     1#include <math.h>
    12#include <stdio.h> /* fprintf */
    23#include <string.h> /* strcmp */
     
    380381{
    381382    char buf[32];
     383    const double nan = sqrt( -1 );
    382384
    383385    tr_snprintf( buf, sizeof( buf ), "%.2f%%", 99.999 );
     
    395397    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( 2.05, 2 ) );
    396398    check( !strcmp( buf, "2.05" ) );
     399
     400    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( 3.3333, 2 ) );
     401    check( !strcmp( buf, "3.33" ) );
     402
     403    tr_snprintf( buf, sizeof( buf ), "%.0f", tr_truncd( 3.3333, 0 ) );
     404    check( !strcmp( buf, "3" ) );
     405
     406    tr_snprintf( buf, sizeof( buf ), "%.2f", tr_truncd( nan, 2 ) );
     407    check( !strcmp( buf, "nan" ) );
    397408
    398409    return 0;
  • trunk/libtransmission/utils.c

    r11331 r11345  
    2525#include <ctype.h> /* isalpha(), tolower() */
    2626#include <errno.h>
     27#include <float.h> /* DBL_EPSILON */
     28#include <locale.h> /* localeconv() */
    2729#include <math.h> /* pow(), fabs(), floor() */
    2830#include <stdarg.h>
     
    14321434
    14331435double
    1434 tr_truncd( double x, int decimal_places )
    1435 {
    1436     /* sigh... surely there's a better way to do this */
    1437     char buf[1024];
    1438     const int i = (int) pow( 10, decimal_places );
    1439     snprintf( buf, sizeof( buf ), "%f", x*i );
    1440     *strchr(buf,'.') = '\0';
    1441     return atof(buf) / i;
     1436tr_truncd( double x, int precision )
     1437{
     1438    char * pt;
     1439    char buf[128];
     1440    const int max_precision = (int) log10( 1.0 / DBL_EPSILON ) - 1;
     1441    tr_snprintf( buf, sizeof( buf ), "%.*f", max_precision, x );
     1442    if(( pt = strstr( buf, localeconv()->decimal_point )))
     1443        pt[precision ? precision+1 : 0] = '\0';
     1444    return atof(buf);
    14421445}
    14431446
Note: See TracChangeset for help on using the changeset viewer.