[INTERPRETER]

* BUG: Fix precision in both string to Float and Float to string 
  conversions.


git-svn-id: svn://localhost/gambas/trunk@4688 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2012-04-28 15:08:24 +00:00
parent b8ab46d135
commit 8fc3cb2d90
4 changed files with 33 additions and 12 deletions

View file

@ -955,16 +955,19 @@ _FORMAT:
if (isfinite(number))
{
number_mant = frexp10(fabs(number), &number_exp);
ndigit = after;
if (!exposant) ndigit += number_exp;
ndigit = MinMax(ndigit, 0, MAX_FLOAT_DIGIT);
//fprintf(stderr, "number_mant = %.24g number_exp = %d ndigit = %d\n", number_mant, number_exp, ndigit);
power = pow10_uint64_p(ndigit + 1);
power = pow10(ndigit + 1);
mantisse = number_mant * power;
if ((mantisse % 10) >= 5)
mantisse += 10;
//fprintf(stderr, "-> power = %" PRId64 " mantisse = %" PRId64 "\n", power, mantisse);
if (mantisse >= power)
{
ndigit = sprintf(buf, ".%" PRId64, mantisse);

View file

@ -23,18 +23,17 @@
#define __GBX_MATH_C
#include "gb_common.h"
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include "gb_common.h"
#include "gb_hash.h"
#include "gbx_math.h"
const double MATH_pow10[] = {
1E-10, 1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3, 1E-2, 0.1, 1,
10, 100, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15, 1E16
};
const double MATH_pow10_double[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
static const uint _pow10_uint[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
/* This is a twisted generalized feedback shift register
that generates pseudo-random numbers.
@ -142,7 +141,7 @@ double frexp10(double x, int *exp)
}
p = (int)log10(x);
x /= pow(10, p);
x /= pow10(p);
if (x >= 1)
{
@ -225,3 +224,17 @@ void MATH_init(void)
HASH_seed = seed;
}
uint64_t pow10_uint64_p(int n)
{
uint64_t v = 1;
while (n > 8)
{
v *= 100000000;
n -= 8;
}
v *= _pow10_uint[n];
return v;
}

View file

@ -31,7 +31,7 @@
#endif
#ifndef __GBX_MATH_C
extern const double MATH_pow10[];
extern const double MATH_pow10_double[];
#endif
void MATH_init(void);
@ -46,7 +46,10 @@ float fixf(float x);
double fix(double x);
double frexp10(double x, int *exp);
#define pow10(_n) (((_n) >= -10 && (_n) <= 16) ? MATH_pow10[(_n) + 10] : exp10(_n))
#define pow10(_n) (((_n) >= 0 && (_n) <= 9) ? MATH_pow10_double[_n] : (((_n) < 0 && (_n) >= -9) ? (1.0 / MATH_pow10_double[-(_n)]) : exp10(_n)))
//#define mulpow10(_v, _n) (((_n) >= 0 && (_n) <= 9) ? ((_v) * MATH_pow10_double[_n]) : (((_n) < 0 && (_n) >= -9) ? ((_v) / MATH_pow10[-(_n)]) : ((_v) * exp10(_n))))
uint64_t pow10_uint64_p(int n);
void randomize(bool set, uint seed);
double rnd(void);

View file

@ -34,7 +34,7 @@
#include "gbx_type.h"
#include "gb_common_buffer.h"
#include "gbx_local.h"
#include "gbx_math.h"
#include "gbx_string.h"
#include "gbx_number.h"
@ -300,7 +300,9 @@ __END:
else
nexp -= ndigit_frac;
*result = ((double)mantisse * pow10(nexp));
//fprintf(stderr, "%.24g %d\n", (double)mantisse, nexp);
//*result = mulpow10((double)mantisse, nexp);
*result = (double)mantisse * pow10(nexp);
return FALSE;
}