~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/decimal.c

MergedĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
122
122
        not in bytes
123
123
*/
124
124
typedef decimal_digit_t dec1;
125
 
typedef longlong      dec2;
 
125
typedef int64_t      dec2;
126
126
 
127
127
#define DIG_PER_DEC1 9
128
128
#define DIG_MASK     100000000
897
897
  if (endp+1 < end_of_string && (*endp == 'e' || *endp == 'E'))
898
898
  {
899
899
    int str_error;
900
 
    longlong exponent= my_strtoll10(endp+1, (char**) &end_of_string,
 
900
    int64_t exponent= my_strtoll10(endp+1, (char**) &end_of_string,
901
901
                                    &str_error);
902
902
 
903
903
    if (end_of_string != endp +1)               /* If at least one digit */
984
984
}
985
985
 
986
986
 
987
 
static int ull2dec(ulonglong from, decimal_t *to)
 
987
static int ull2dec(uint64_t from, decimal_t *to)
988
988
{
989
989
  int intg1, error=E_DEC_OK;
990
 
  ulonglong x=from;
 
990
  uint64_t x=from;
991
991
  dec1 *buf;
992
992
 
993
993
  sanity(to);
1003
1003
 
1004
1004
  for (buf=to->buf+intg1; intg1; intg1--)
1005
1005
  {
1006
 
    ulonglong y=x/DIG_BASE;
 
1006
    uint64_t y=x/DIG_BASE;
1007
1007
    *--buf=(dec1)(x-y*DIG_BASE);
1008
1008
    x=y;
1009
1009
  }
1010
1010
  return error;
1011
1011
}
1012
1012
 
1013
 
int ulonglong2decimal(ulonglong from, decimal_t *to)
 
1013
int uint64_t2decimal(uint64_t from, decimal_t *to)
1014
1014
{
1015
1015
  to->sign=0;
1016
1016
  return ull2dec(from, to);
1017
1017
}
1018
1018
 
1019
 
int longlong2decimal(longlong from, decimal_t *to)
 
1019
int int64_t2decimal(int64_t from, decimal_t *to)
1020
1020
{
1021
1021
  if ((to->sign= from < 0))
1022
1022
    return ull2dec(-from, to);
1023
1023
  return ull2dec(from, to);
1024
1024
}
1025
1025
 
1026
 
int decimal2ulonglong(decimal_t *from, ulonglong *to)
 
1026
int decimal2uint64_t(decimal_t *from, uint64_t *to)
1027
1027
{
1028
1028
  dec1 *buf=from->buf;
1029
 
  ulonglong x=0;
 
1029
  uint64_t x=0;
1030
1030
  int intg, frac;
1031
1031
 
1032
1032
  if (from->sign)
1037
1037
 
1038
1038
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1039
1039
  {
1040
 
    ulonglong y=x;
 
1040
    uint64_t y=x;
1041
1041
    x=x*DIG_BASE + *buf++;
1042
 
    if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
 
1042
    if (unlikely(y > ((uint64_t) ULONGLONG_MAX/DIG_BASE) || x < y))
1043
1043
    {
1044
1044
      *to=ULONGLONG_MAX;
1045
1045
      return E_DEC_OVERFLOW;
1052
1052
  return E_DEC_OK;
1053
1053
}
1054
1054
 
1055
 
int decimal2longlong(decimal_t *from, longlong *to)
 
1055
int decimal2int64_t(decimal_t *from, int64_t *to)
1056
1056
{
1057
1057
  dec1 *buf=from->buf;
1058
 
  longlong x=0;
 
1058
  int64_t x=0;
1059
1059
  int intg, frac;
1060
1060
 
1061
1061
  for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
1062
1062
  {
1063
 
    longlong y=x;
 
1063
    int64_t y=x;
1064
1064
    /*
1065
1065
      Attention: trick!
1066
1066
      we're calculating -|from| instead of |from| here
1357
1357
    }
1358
1358
    from+=i;
1359
1359
    *buf=x ^ mask;
1360
 
    if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
 
1360
    if (((uint64_t)*buf) >= (uint64_t) powers10[intg0x+1])
1361
1361
      goto err;
1362
1362
    if (buf > to->buf || *buf != 0)
1363
1363
      buf++;
2522
2522
  printf("\n");
2523
2523
}
2524
2524
 
2525
 
void test_ull2d(ulonglong from, const char *orig, int ex)
 
2525
void test_ull2d(uint64_t from, const char *orig, int ex)
2526
2526
{
2527
2527
  char s[100];
2528
2528
  int res;
2529
2529
 
2530
 
  res=ulonglong2decimal(from, &a);
2531
 
  longlong10_to_str(from,s,10);
 
2530
  res=uint64_t2decimal(from, &a);
 
2531
  int64_t10_to_str(from,s,10);
2532
2532
  printf("%-40s => res=%d    ", s, res);
2533
2533
  print_decimal(&a, orig, res, ex);
2534
2534
  printf("\n");
2535
2535
}
2536
2536
 
2537
 
void test_ll2d(longlong from, const char *orig, int ex)
 
2537
void test_ll2d(int64_t from, const char *orig, int ex)
2538
2538
{
2539
2539
  char s[100];
2540
2540
  int res;
2541
2541
 
2542
 
  res=longlong2decimal(from, &a);
2543
 
  longlong10_to_str(from,s,-10);
 
2542
  res=int64_t2decimal(from, &a);
 
2543
  int64_t10_to_str(from,s,-10);
2544
2544
  printf("%-40s => res=%d    ", s, res);
2545
2545
  print_decimal(&a, orig, res, ex);
2546
2546
  printf("\n");
2549
2549
void test_d2ull(const char *s, const char *orig, int ex)
2550
2550
{
2551
2551
  char s1[100], *end;
2552
 
  ulonglong x;
 
2552
  uint64_t x;
2553
2553
  int res;
2554
2554
 
2555
2555
  end= strend(s);
2556
2556
  string2decimal(s, &a, &end);
2557
 
  res=decimal2ulonglong(&a, &x);
 
2557
  res=decimal2uint64_t(&a, &x);
2558
2558
  if (full) dump_decimal(&a);
2559
 
  longlong10_to_str(x,s1,10);
 
2559
  int64_t10_to_str(x,s1,10);
2560
2560
  printf("%-40s => res=%d    %s\n", s, res, s1);
2561
2561
  check_result_code(res, ex);
2562
2562
  if (orig && strcmp(orig, s1))
2569
2569
void test_d2ll(const char *s, const char *orig, int ex)
2570
2570
{
2571
2571
  char s1[100], *end;
2572
 
  longlong x;
 
2572
  int64_t x;
2573
2573
  int res;
2574
2574
 
2575
2575
  end= strend(s);
2576
2576
  string2decimal(s, &a, &end);
2577
 
  res=decimal2longlong(&a, &x);
 
2577
  res=decimal2int64_t(&a, &x);
2578
2578
  if (full) dump_decimal(&a);
2579
 
  longlong10_to_str(x,s1,-10);
 
2579
  int64_t10_to_str(x,s1,-10);
2580
2580
  printf("%-40s => res=%d    %s\n", s, res, s1);
2581
2581
  check_result_code(res, ex);
2582
2582
  if (orig && strcmp(orig, s1))
2809
2809
  test_f2d(0.00012345000098765, 0);
2810
2810
  test_f2d(1234500009876.5, 0);
2811
2811
 
2812
 
  printf("==== ulonglong2decimal ====\n");
 
2812
  printf("==== uint64_t2decimal ====\n");
2813
2813
  test_ull2d(12345ULL, "12345", 0);
2814
2814
  test_ull2d(0ULL, "0", 0);
2815
2815
  test_ull2d(18446744073709551615ULL, "18446744073709551615", 0);
2816
2816
 
2817
 
  printf("==== decimal2ulonglong ====\n");
 
2817
  printf("==== decimal2uint64_t ====\n");
2818
2818
  test_d2ull("12345", "12345", 0);
2819
2819
  test_d2ull("0", "0", 0);
2820
2820
  test_d2ull("18446744073709551615", "18446744073709551615", 0);
2823
2823
  test_d2ull("1.23", "1", 1);
2824
2824
  test_d2ull("9999999999999999999999999.000", "9999999999999999", 2);
2825
2825
 
2826
 
  printf("==== longlong2decimal ====\n");
 
2826
  printf("==== int64_t2decimal ====\n");
2827
2827
  test_ll2d(12345LL, "-12345", 0);
2828
2828
  test_ll2d(1LL, "-1", 0);
2829
2829
  test_ll2d(9223372036854775807LL, "-9223372036854775807", 0);
2830
2830
  test_ll2d(9223372036854775808ULL, "-9223372036854775808", 0);
2831
2831
 
2832
 
  printf("==== decimal2longlong ====\n");
 
2832
  printf("==== decimal2int64_t ====\n");
2833
2833
  test_d2ll("18446744073709551615", "18446744073", 2);
2834
2834
  test_d2ll("-1", "-1", 0);
2835
2835
  test_d2ll("-1.23", "-1", 1);