[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:
parent
b8ab46d135
commit
8fc3cb2d90
4 changed files with 33 additions and 12 deletions
|
@ -955,16 +955,19 @@ _FORMAT:
|
||||||
if (isfinite(number))
|
if (isfinite(number))
|
||||||
{
|
{
|
||||||
number_mant = frexp10(fabs(number), &number_exp);
|
number_mant = frexp10(fabs(number), &number_exp);
|
||||||
|
|
||||||
ndigit = after;
|
ndigit = after;
|
||||||
if (!exposant) ndigit += number_exp;
|
if (!exposant) ndigit += number_exp;
|
||||||
ndigit = MinMax(ndigit, 0, MAX_FLOAT_DIGIT);
|
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;
|
mantisse = number_mant * power;
|
||||||
if ((mantisse % 10) >= 5)
|
if ((mantisse % 10) >= 5)
|
||||||
mantisse += 10;
|
mantisse += 10;
|
||||||
|
|
||||||
|
//fprintf(stderr, "-> power = %" PRId64 " mantisse = %" PRId64 "\n", power, mantisse);
|
||||||
|
|
||||||
if (mantisse >= power)
|
if (mantisse >= power)
|
||||||
{
|
{
|
||||||
ndigit = sprintf(buf, ".%" PRId64, mantisse);
|
ndigit = sprintf(buf, ".%" PRId64, mantisse);
|
||||||
|
|
|
@ -23,18 +23,17 @@
|
||||||
|
|
||||||
#define __GBX_MATH_C
|
#define __GBX_MATH_C
|
||||||
|
|
||||||
|
#include "gb_common.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "gb_common.h"
|
|
||||||
#include "gb_hash.h"
|
#include "gb_hash.h"
|
||||||
#include "gbx_math.h"
|
#include "gbx_math.h"
|
||||||
|
|
||||||
const double MATH_pow10[] = {
|
const double MATH_pow10_double[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
|
||||||
1E-10, 1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3, 1E-2, 0.1, 1,
|
static const uint _pow10_uint[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
|
||||||
10, 100, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15, 1E16
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is a twisted generalized feedback shift register
|
/* This is a twisted generalized feedback shift register
|
||||||
that generates pseudo-random numbers.
|
that generates pseudo-random numbers.
|
||||||
|
@ -142,7 +141,7 @@ double frexp10(double x, int *exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
p = (int)log10(x);
|
p = (int)log10(x);
|
||||||
x /= pow(10, p);
|
x /= pow10(p);
|
||||||
|
|
||||||
if (x >= 1)
|
if (x >= 1)
|
||||||
{
|
{
|
||||||
|
@ -225,3 +224,17 @@ void MATH_init(void)
|
||||||
|
|
||||||
HASH_seed = seed;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __GBX_MATH_C
|
#ifndef __GBX_MATH_C
|
||||||
extern const double MATH_pow10[];
|
extern const double MATH_pow10_double[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void MATH_init(void);
|
void MATH_init(void);
|
||||||
|
@ -46,7 +46,10 @@ float fixf(float x);
|
||||||
double fix(double x);
|
double fix(double x);
|
||||||
double frexp10(double x, int *exp);
|
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);
|
void randomize(bool set, uint seed);
|
||||||
double rnd(void);
|
double rnd(void);
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "gbx_type.h"
|
#include "gbx_type.h"
|
||||||
#include "gb_common_buffer.h"
|
#include "gb_common_buffer.h"
|
||||||
#include "gbx_local.h"
|
#include "gbx_local.h"
|
||||||
|
#include "gbx_math.h"
|
||||||
#include "gbx_string.h"
|
#include "gbx_string.h"
|
||||||
#include "gbx_number.h"
|
#include "gbx_number.h"
|
||||||
|
|
||||||
|
@ -300,7 +300,9 @@ __END:
|
||||||
else
|
else
|
||||||
nexp -= ndigit_frac;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue